Le monde flou du bruit de Perlin

image

Qu'est-ce que le bruit Perlin?


Le bruit de Perlin a été inventé en 1983 par Ken Perlin (qui a reçu un prix de l'American Academy of Motion Picture Arts and Sciences pour cette réalisation). Vous voyez, à cette époque, tout le monde recherchait le photoréalisme, mais cela faisait toujours défaut. Ken Perlin a inventé cet algorithme de bruit pour se débarrasser de l'apparence misérable des "ordinateurs" des modèles 3D. Le bruit est un générateur de nombres aléatoires en infographie. Il s'agit d'un motif aléatoire et non structuré, et est utile lorsque vous avez besoin d'une source de pièces détaillées qui manquent dans la structure évidente 1 . Le bruit de Perlin est un algorithme multidimensionnel utilisé dans la génération procédurale, les textures, la génération de terrain, la génération de cartes, la génération de surfaces, la génération de sommets, etc. Le tableau ci-dessous 2 montre les limites des possibilités de bruit Perlin:

DimensionBruit brut (niveaux de gris)Candidature
1

Objets vectoriels à la main
2
Objets tels que les textures procédurales et les flammes
3
Perlin Noise utilisé dans Minecraft Relief

Perlin a donné la définition suivante du bruit: le bruit est une approximation du bruit blanc, limité à une plage d'une octave 3 . La définition officielle du bruit est la suivante:

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


O Where N(x)- fonction bruit. Le bruit de Perlin est un bruit procédural . «L'adjectif procédural est utilisé en informatique pour séparer les entités décrites par le code du programme de celles décrites par les structures de données.» 4 C'est-à-dire, quelque chose généré , et pas dur. À quoi sert le bruit procédural au lieu, par exemple, de créer du bruit manuellement? Le bruit procédural est compact , c'est-à-dire qu'il prend moins de place. Elle est inextricable , c'est-à-dire apériodique . Il est paramétrique , il est accessible de façon aléatoire ; il a aussi bien d'autres avantages qui simplifient la vie de l'artiste ... Mais n'est-ce pas notre but ultime - servir l'artiste? Hier, j'ai créé un plug-in pour After Effects, qui peut être vu dans mon post précédent. Je n'ai pas pris en compte les intérêts de l'artiste en lui, seulement les intérêts de mon ego, donc personne ne l'a téléchargé. J'ai compris la leçon: servez l'artiste, pas vous-même.

Avant Perlin, le bruit des gradients des réseaux est apparu. Ils ont été générés par interpolation entre des valeurs aléatoires et dans le bruit de Perlin, un réseau cubique est utilisé pour chaque sommet, puis une interpolation spline est effectuée. «Un gradient pseudo-aléatoire est obtenu en hachant le point du réseau et en utilisant le résultat pour sélectionner le gradient.» 5 Ces hachages se transforment en 12 vecteurs et sont interpolés du centre vers les bords à l'aide d'un polynôme du cinquième degré. C'est difficile à imaginer, non? Ne t'inquiète pas. Je vais le montrer dans les images 6 et dans le pseudo-code 7 .


"... sont interpolés du centre vers les bords à l'aide d'un polynôme du cinquième degré"

Et voici le pseudocode Perlin classique sans fonction de hachage:

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

Il convient également de savoir que «toutes les fonctions de bruit, à l'exception du bruit de Perlin et du bruit de convolution raréfié, sont approximativement de type bande. Le bruit de Perlin n'est qu'une bande faible, ce qui peut entraîner des problèmes de distorsion et de perte de détails. » 8 De plus, le bruit Perlin n'a pas de distribution d'amplitude gaussienne. Autrement dit, les taches de bruit ne sont pas diffusées sur la base d'une fonction gaussienne, ce que nous ne considérerons pas dans cet article. Il y a beaucoup de choses dans lesquelles Perlin est très à l'aise, mais il y a des choses dans lesquelles il est très faible. Dans le tableau ci-dessous 9, vous pouvez le voir vous-même.



Bruit Perlin en pratique: implémentations GLSL


Parlons donc du bruit de Perlin sur GLSL. Le bruit Perlin peut être utilisé comme une onde, comme une couleur diffuse, comme un matériau diffus, comme une lumière vacillante ou comme des taches sur une texture. Personnellement, je l'ai utilisé dans cet exemple comme un scintillement de couleur.


Au moment où j'écris cet article, je songe à créer un plug-in pour After Effects qui ajoute la fonctionnalité de bruit Perlin.

Le bruit le plus simple de Perlin peut être créé 10 comme suit:

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

Cependant, il s'agit d'une version refaite du bruit de Perlin, qui a été créée en 2002. Allez à Gist pour voir comment le bruit classique de Perlin est réalisé.

Eh bien, c'est tout pour aujourd'hui. Un court article, je sais, et il manque de contenu original, mais jusqu'à présent, je n'ai plus d'idées, car je n'ai pas encore lu le rendu en temps réel . Ce livre est plein de concepts et d'idées pour l'apprentissage et l'apprentissage. Je l'aime!


En parallèle, je lis un autre livre - Fundamentals of Computer Graphics . Je suis un peu coincé sur le sujet des courbes implicites, mais je vais demander à mon parent titulaire d'un doctorat en mathématiques de m'aider.


Les références


  • A Survey of Procedural Noise Functions, Computer Graphics Forum, Volume 29 (2010), Numéro 8, pp 2379-2600
  • Bruit de calcul efficace, Journal of Graphics Tools Volume 16, No. 2: 85-94

  1. Une enquête, 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. De flafla2.imtqy.com/2014/08/09/perlinnoise.html
  7. De Wikipédia
  8. A. Lagae et al
  9. Adapté de A. Lagae, et al
  10. gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83

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


All Articles