Perlins verschwommene Lärmwelt

Bild

Was ist Perlin-Lärm?


Perlins Lärm wurde 1983 von Ken Perlin erfunden (der für diese Leistung eine Auszeichnung von der American Academy of Motion Picture Arts and Sciences erhielt). Sie sehen, in jenen Tagen strebten alle nach Fotorealismus, aber es fehlte immer. Ken Perlin hat diesen Rauschalgorithmus erfunden, um das miserable "Computer" -Erscheinungsbild von 3D-Modellen zu beseitigen. Rauschen ist ein Zufallszahlengenerator in der Computergrafik. Dies ist ein zufälliges, unstrukturiertes Muster und nützlich, wenn Sie eine Quelle für detaillierte Teile benötigen, die in der offensichtlichen Struktur 1 fehlen. Perlin-Rauschen ist ein mehrdimensionaler Algorithmus, der bei der Prozedurgenerierung, Texturierung, Höhengenerierung, Kartengenerierung, Oberflächengenerierung, Scheitelpunktgenerierung usw. verwendet wird. Die folgende Tabelle 2 zeigt die Grenzen der Möglichkeiten von Perlin-Rauschen:

DimensionRohes Rauschen (Graustufen)Anwendung
1

Vektorobjekte, die handgezeichnet schauen
2
Objekte wie prozedurale Texturen und Flammen
3
Perlin-Lärm, der in Minecraft Relief verwendet wird

Perlin gab die folgende Definition von Rauschen an: Rauschen ist eine Annäherung an weißes Rauschen, begrenzt auf einen Bereich von einer Oktave 3 . Die formale Definition von Lärm lautet wie folgt:

fN(y1,y2, cdots,yn;x1,x2, cdots,xn)=P(N(x1),N(x2), cdots,N(xn))


Wo N(x)- Rauschfunktion. Perlins Lärm ist prozeduraler Lärm. "Das Adjektiv prozedural wird in der Informatik verwendet, um durch Programmcode beschriebene Entitäten von den durch Datenstrukturen beschriebenen zu trennen." 4 Das heißt, etwas generiert und nicht hart gesetzt. Was ist gut daran, prozedurales Rauschen zu verwenden, anstatt beispielsweise manuell Rauschen zu erzeugen? Das prozedurale Rauschen ist kompakt , d. H. Es nimmt weniger Platz ein. Es ist untrennbar , dh aperiodisch . Es ist parametrisch , es kann zufällig zugegriffen werden; Er hat auch viele andere Vorteile, die das Leben des Künstlers vereinfachen ... Aber ist das nicht unser oberstes Ziel - dem Künstler zu dienen? Gestern habe ich ein Plug-In für After Effects erstellt, das in meinem vorherigen Beitrag zu sehen ist. Ich habe nicht die Interessen des Künstlers an ihm berücksichtigt, sondern nur die Interessen meines Ego, also hat es niemand heruntergeladen. Ich habe die Lektion verstanden: Diene dem Künstler, nicht dir selbst.

Vor Perlin trat das Rauschen der Steigungen der Gitter auf. Sie wurden durch Interpolation zwischen Zufallswerten erzeugt, und im Perlin-Rauschen wird für jeden Scheitelpunkt ein kubisches Gitter verwendet, und dann wird eine Spline- Interpolation durchgeführt. „Ein pseudozufälliger Gradient wird erhalten, indem der Gitterpunkt gehasht und das Ergebnis zur Auswahl des Gradienten verwendet wird.“ 5 Diese Hashes werden zu 12 Vektoren und werden von der Mitte bis zu den Kanten unter Verwendung eines Polynoms fünften Grades interpoliert. Es ist schwer vorstellbar, oder? Keine Sorge. Ich werde dies in Bildern 6 und in Pseudocode 7 zeigen .


"... werden von der Mitte bis zu den Kanten mit einem Polynom fünften Grades interpoliert"

Und hier ist der klassische Perlin-Pseudocode ohne Hash-Funktion:

// 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; } 

Es ist auch wichtig zu wissen, dass „alle Rauschfunktionen außer Perlin-Rauschen und verdünntem Faltungsrauschen ungefähr streifenartig sind. Das Rauschen von Perlin ist nur schwach, was zu Problemen mit Verzerrungen und Detailverlust führen kann. “ 8 Außerdem hat Perlin-Rauschen keine Gaußsche Amplitudenverteilung. Das heißt, Rauschflecken werden nicht auf der Basis einer Gaußschen Funktion gestreut, die wir in diesem Artikel nicht berücksichtigen werden. Es gibt viele Dinge, in denen Perlin sich sehr wohl fühlt, aber es gibt Dinge, in denen er sehr schwach ist. In der Tabelle unter 9 können Sie es selbst sehen.



Perlin-Rauschen in der Praxis: GLSL-Implementierungen


Sprechen wir also über Perlins Lärm auf GLSL. Perlin-Rauschen kann als Welle, als diffuse Farbe, als diffuses Material, als flackerndes Licht oder als Flecken auf einer Textur verwendet werden. Persönlich habe ich es in diesem Beispiel als Farbflimmern verwendet.


Während ich diesen Artikel schreibe, denke ich darüber nach, ein Plug-In für After Effects zu erstellen, das die Perlin-Rauschfunktionalität hinzufügt.

Perlins einfachstes Rauschen kann wie folgt erzeugt werden:

 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); } 

Dies ist jedoch eine überarbeitete Version von Perlins Rauschen, das 2002 erstellt wurde. Gehen Sie zu Gist, um zu sehen, wie Perlins klassisches Rauschen realisiert wird.

Nun, das ist alles für heute. Ein kurzer Beitrag, ich weiß, und es fehlen Originalinhalte, aber bisher sind mir die Ideen ausgegangen, weil ich Real-Time-Rendering noch nicht gelesen habe. Dieses Buch ist voller Konzepte und Ideen zum Lernen und Lernen. Ich liebe sie!


Parallel dazu lese ich ein anderes Buch - Grundlagen der Computergrafik . Ich bin ein wenig beim Thema Implizite Kurven festgefahren, aber ich werde meinen Verwandten mit einem Doktortitel in Mathematik bitten, mir zu helfen.


Referenzen


  • Eine Übersicht über prozedurale Rauschfunktionen, Computer Graphics Forum, Band 29 (2010), Nummer 8, S. 2379-2600
  • Efficient Computational Noise, Journal of Graphics Tools, Band 16, Nr. 2: 85-94

  1. Eine Umfrage et al
  2. flafla2.imtqy.com/2014/08/09/perlinnoise.html
  3. A. Lagaue et al
  4. A. Lagae et al
  5. A. Lagae et al
  6. Von flafla2.imtqy.com/2014/08/09/perlinnoise.html
  7. Aus Wikipedia
  8. A. Lagae et al
  9. Adaptiert von A. Lagae et al
  10. gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83

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


All Articles