عالم بيرلين الغامض من الضوضاء

الصورة

ما هو بيرلين الضوضاء؟


اخترع ضجيج بيرلين في عام 1983 من قبل كين بيرلين (الذي حصل على جائزة من الأكاديمية الأمريكية لفنون وعلوم الصور المتحركة لهذا الإنجاز). كما ترون ، في تلك الأيام كان الجميع يناضل من أجل الواقعية الواقعية ، لكنه كان ينقصه دائمًا. اخترع كين بيرلين خوارزمية الضجيج هذه للتخلص من المظهر البائس للنماذج ثلاثية الأبعاد. الضوضاء هي مولد رقم عشوائي في رسومات الكمبيوتر. هذا نمط عشوائي غير منظم ، وهو مفيد عندما تحتاج إلى مصدر لأجزاء مفصلة تفتقر إلى البنية الواضحة 1 . ضجيج بيرلين هو خوارزمية متعددة الأبعاد تستخدم في التوليد الإجرائي ، والقوام ، وتوليد الارتفاع ، وتوليد الخرائط ، وتوليد السطح ، وتوليد قمة الرأس ، وما إلى ذلك. يوضح الجدول أدناه 2 حدود إمكانيات ضوضاء بيرلين:

البعدالضوضاء الخام (تدرج الرمادي)التطبيق
1

كائنات متجهة تبحث مرسومة باليد
2
كائنات مثل القوام الإجرائية واللهب
3
بيرلين الضوضاء المستخدمة في ماين كرافت الإغاثة

أعطى بيرلين التعريف التالي للضوضاء: الضجيج هو تقريب للضوضاء البيضاء ، ويقتصر على مجموعة من أوكتاف واحد 3 . التعريف الرسمي للضوضاء هو كما يلي:

fN(y1،y2، cdots،yn؛x1،x2، cdots،xn)=P(N(x1)،N(x2)، cdots،N(xn))


أين N(x)- وظيفة الضوضاء. ضجيج بيرلين هو ضجيج إجرائي . " يتم استخدام الإجراء الصفري في علوم الكمبيوتر لفصل الكيانات التي تم وصفها بواسطة رمز البرنامج عن تلك الموصوفة في هياكل البيانات." وهذا هو ، شيء تم إنشاؤه ، وليس مجموعة الثابت. ما فائدة استخدام الضوضاء الإجرائية بدلاً من ، على سبيل المثال ، إنشاء الضوضاء يدويًا؟ الضجيج الإجرائي مضغوط ، أي مساحة أقل. انها لا تنفصم ، وهذا هو ، aperiodic . هو حدودي ، يمكن الوصول إليها بشكل عشوائي . لديه أيضًا العديد من المزايا الأخرى التي تبسط حياة الفنان ... لكن أليس هذا هو هدفنا النهائي - خدمة الفنان؟ قمت أمس بإنشاء مكون إضافي لـ After Effects ، والذي يمكن رؤيته في مشاركتي السابقة. لم أضع في الاعتبار اهتمامات الفنان فيه ، بل اهتماماتي الشخصية ، لذلك لم يقم أحد بتنزيلها. فهمت الدرس: خدم الفنان ، وليس نفسك.

قبل بيرلين ، ظهر ضجيج التدرجات. تم إنشاؤها عن طريق الاستيفاء بين القيم العشوائية ، وفي ضوضاء بيرلين ، يتم استخدام شعرية مكعب لكل قمة ، ومن ثم يتم تنفيذ الاستيفاء الخيطي . "يتم الحصول على التدرج العشوائي الزائف عن طريق تجزئة نقطة الشبكة واستخدام النتيجة لتحديد التدرج." 5 تتحول هذه التجزئات إلى 12 متجهًا ويتم تحريفها من المركز إلى الحواف باستخدام كثير الحدود من الدرجة الخامسة. من الصعب أن نتخيل ، أليس كذلك؟ لا تقلق سأعرض هذا في الصور 6 وفي الكود الزائف 7 .


"... محرف من الوسط إلى الحواف باستخدام متعدد الحدود من الدرجة الخامسة"

وهنا هو بيرود الكود الكلاسيكي دون وظيفة تجزئة:

// Function to linearly interpolate between a0 and a1 // Weight w should be in the range [0.0, 1.0] float lerp(float a0, float a1, float w) { return (1.0 - w)*a0 + w*a1; // as an alternative, this slightly faster equivalent formula can be used: // return a0 + w*(a1 - a0); } // Computes the dot product of the distance and gradient vectors. float dotGridGradient(int ix, int iy, float x, float y) { // Precomputed (or otherwise) gradient vectors at each grid node extern float Gradient[IYMAX][IXMAX][2]; // Compute the distance vector float dx = x - (float)ix; float dy = y - (float)iy; // Compute the dot-product return (dx*Gradient[iy][ix][0] + dy*Gradient[iy][ix][1]); } // Compute Perlin noise at coordinates x, y float perlin(float x, float y) { // Determine grid cell coordinates int x0 = int(x); int x1 = x0 + 1; int y0 = int(y); int y1 = y0 + 1; // Determine interpolation weights // Could also use higher order polynomial/s-curve here float sx = x - (float)x0; float sy = y - (float)y0; // Interpolate between grid point gradients float n0, n1, ix0, ix1, value; n0 = dotGridGradient(x0, y0, x, y); n1 = dotGridGradient(x1, y0, x, y); ix0 = lerp(n0, n1, sx); n0 = dotGridGradient(x0, y1, x, y); n1 = dotGridGradient(x1, y1, x, y); ix1 = lerp(n0, n1, sx); value = lerp(ix0, ix1, sy); return value; } 

تجدر الإشارة أيضًا إلى أن "جميع وظائف الضوضاء ، باستثناء ضوضاء Perlin وضوضاء الالتواء غير المنتظمة ، تشبه الشريط تقريبًا. ضجيج بيرلين هو نطاق ضعيف فقط ، مما قد يؤدي إلى مشاكل في التشويه وفقدان التفاصيل. " 8 بالإضافة إلى ذلك ، لا يوجد في بيرلين ضوضاء توزيع سعة غاوسي. وهذا يعني ، لا تنتشر بقع الضوضاء على أساس وظيفة غوسية ، والتي لن نأخذها في الاعتبار في هذه المقالة. هناك العديد من الأشياء التي يكون فيها بيرلين مرتاحًا جدًا ، ولكن هناك أشياء يكون ضعيفًا للغاية فيها. في الجدول أدناه 9 يمكنك أن ترى ذلك بنفسك.



ضجيج بيرلين في الممارسة: تطبيقات GLSL


لذلك ، دعونا نتحدث عن ضجيج بيرلين على GLSL. يمكن استخدام ضوضاء Perlin كموجة أو لون منتشر أو مادة منتشرة أو كمصباح وميض أو كمواقع على نسيج. أنا شخصياً استخدمته في هذا المثال باعتباره وميضًا من الألوان.


أثناء كتابة هذا المقال ، أفكر في إنشاء مكون إضافي لـ After Effects يضيف وظيفة ضوضاء Perlin.

يمكن إنشاء أبسط ضوضاء لـ Perlin 10 على النحو التالي:

 float rand(vec2 c){ return fract(sin(dot(c.xy ,vec2(12.9898,78.233))) * 43758.5453); } float noise(vec2 p, float freq ){ float unit = screenWidth/freq; vec2 ij = floor(p/unit); vec2 xy = mod(p,unit)/unit; //xy = 3.*xy*xy-2.*xy*xy*xy; xy = .5*(1.-cos(PI*xy)); float a = rand((ij+vec2(0.,0.))); float b = rand((ij+vec2(1.,0.))); float c = rand((ij+vec2(0.,1.))); float d = rand((ij+vec2(1.,1.))); float x1 = mix(a, b, xy.x); float x2 = mix(c, d, xy.x); return mix(x1, x2, xy.y); } float pNoise(vec2 p, int res){ float persistance = .5; float n = 0.; float normK = 0.; float f = 4.; float amp = 1.; int iCount = 0; for (int i = 0; i<50; i++){ n+=amp*noise(p, f); f*=2.; normK+=amp; amp*=persistance; if (iCount == res) break; iCount++; } float nf = n/normK; return nf*nf*nf*nf; } 


 #define M_PI 3.14159265358979323846 float rand(vec2 co){return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);} float rand (vec2 co, float l) {return rand(vec2(rand(co), l));} float rand (vec2 co, float l, float t) {return rand(vec2(rand(co, l), t));} float perlin(vec2 p, float dim, float time) { vec2 pos = floor(p * dim); vec2 posx = pos + vec2(1.0, 0.0); vec2 posy = pos + vec2(0.0, 1.0); vec2 posxy = pos + vec2(1.0); float c = rand(pos, dim, time); float cx = rand(posx, dim, time); float cy = rand(posy, dim, time); float cxy = rand(posxy, dim, time); vec2 d = fract(p * dim); d = -0.5 * cos(d * M_PI) + 0.5; float ccx = mix(c, cx, dx); float cycxy = mix(cy, cxy, dx); float center = mix(ccx, cycxy, dy); return center * 2.0 - 1.0; } // p must be normalized! float perlin(vec2 p, float dim) { /*vec2 pos = floor(p * dim); vec2 posx = pos + vec2(1.0, 0.0); vec2 posy = pos + vec2(0.0, 1.0); vec2 posxy = pos + vec2(1.0); // For exclusively black/white noise /*float c = step(rand(pos, dim), 0.5); float cx = step(rand(posx, dim), 0.5); float cy = step(rand(posy, dim), 0.5); float cxy = step(rand(posxy, dim), 0.5);*/ /*float c = rand(pos, dim); float cx = rand(posx, dim); float cy = rand(posy, dim); float cxy = rand(posxy, dim); vec2 d = fract(p * dim); d = -0.5 * cos(d * M_PI) + 0.5; float ccx = mix(c, cx, dx); float cycxy = mix(cy, cxy, dx); float center = mix(ccx, cycxy, dy); return center * 2.0 - 1.0;*/ return perlin(p, dim, 0.0); } 

ومع ذلك ، هذا هو نسخة إعادة بنائها من الضوضاء بيرلين ، الذي تم إنشاؤه في عام 2002. انتقل إلى Gist لترى كيف تتحقق ضوضاء Perlin الكلاسيكية.

حسنًا ، هذا كل شيء لهذا اليوم. أعرف أن هناك وظيفة قصيرة ، وهي تفتقر إلى المحتوى الأصلي ، لكنني نفدت الأفكار حتى الآن ، لأنني لم أقرأ العرض في الوقت الحقيقي حتى الآن. هذا الكتاب مليء بالمفاهيم والأفكار للتعلم والتعلم. أنا أحبها!


في موازاة ذلك ، أقرأ كتابًا آخر - أساسيات رسومات الحاسوب . لقد علقت قليلاً حول موضوع المنحنيات الضمنية ، لكنني سأطلب من قريبتي الحاصلة على درجة الدكتوراه في الرياضيات مساعدتي.


المراجع


  • دراسة استقصائية لوظائف الضوضاء الإجرائية ، منتدى رسومات الحاسوب ، المجلد 29 (2010) ، العدد 8 ، الصفحات 2379-2600
  • الضوضاء الحسابية الفعالة ، مجلة أدوات الرسومات المجلد 16 ، رقم 2: 85-94

  1. مسح ، وآخرون
  2. flafla2.imtqy.com/2014/08/09/perlinnoise.html
  3. A. Lagaue et al
  4. أ. لاجي ، وآخرون
  5. أ. لاجي ، وآخرون
  6. من flafla2.imtqy.com/2014/08/09/perlinnoise.html
  7. من ويكيبيديا
  8. أ. لاجي ، وآخرون
  9. مقتبس من A. Lagae ، وآخرون
  10. gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83

Source: https://habr.com/ru/post/ar441312/


All Articles