El difuso mundo de ruido de Perlin

imagen

¿Qué es el ruido Perlin?


El ruido de Perlin fue inventado en 1983 por Ken Perlin (quien recibió un premio de la Academia Estadounidense de Artes y Ciencias Cinematográficas por este logro). Verá, en esos días todos luchaban por el fotorrealismo, pero siempre faltaba. Ken Perlin inventó este algoritmo de ruido para deshacerse de la miserable apariencia de "computadora" de los modelos 3D. El ruido es un generador de números aleatorios en gráficos de computadora. Este es un patrón aleatorio, no estructurado, y es útil cuando necesita una fuente de partes detalladas que faltan en la estructura obvia 1 . El ruido Perlin es un algoritmo multidimensional utilizado en la generación de procedimientos, texturas, generación de elevación, generación de mapas, generación de superficie, generación de vértices, y así sucesivamente. La tabla a continuación 2 muestra los límites de las capacidades de ruido perlin:

DimensiónRuido crudo (escala de grises)Solicitud
1

Objetos vectoriales que parecen dibujados a mano
2
Objetos como texturas de procedimiento y llamas.
3
Ruido Perlin utilizado en el alivio de Minecraft

Perlin dio la siguiente definición de ruido: el ruido es una aproximación al ruido blanco, limitado a un rango de una octava 3 . La definición formal de ruido es la siguiente:

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


Donde N(x)- Función de ruido. El ruido de Perlin es ruido de procedimiento . "El adjetivo procesal se utiliza en informática para separar las entidades descritas por el código del programa de las descritas por las estructuras de datos". 4 Es decir, algo generado , y no establecido duro. ¿Qué es bueno usar ruido de procedimiento en lugar de, por ejemplo, crear ruido manualmente? El ruido de procedimiento es compacto , es decir, ocupa menos espacio. Es inextricable , es decir, aperiódico . Es paramétrico , se puede acceder al azar ; él también tiene muchas otras ventajas que simplifican la vida del artista ... ¿Pero no es este nuestro objetivo final: servir al artista? Ayer creé un complemento para After Effects, que se puede ver en mi publicación anterior. No tomé en cuenta los intereses del artista en él, solo los intereses de mi ego, por lo que nadie lo descargó. Comprendí la lección: Servir al artista, no a ti mismo.

Antes de Perlin, apareció el ruido de los gradientes de las rejillas. Se generaron por interpolación entre valores aleatorios, y en el ruido de Perlin, se utiliza una red cúbica para cada vértice, y luego se realiza la interpolación spline . "Se obtiene un gradiente pseudoaleatorio al trocear el punto reticular y usar el resultado para seleccionar el gradiente". 5 Estos hashes se convierten en 12 vectores y se interpolan desde el centro hasta los bordes utilizando un polinomio de quinto grado. Es difícil de imaginar, ¿verdad? No te preocupes Mostraré esto en las imágenes 6 y en el pseudocódigo 7 .


"... se interpolan desde el centro hasta los bordes utilizando un polinomio de quinto grado"

Y aquí está el pseudocódigo clásico de Perlin sin una función hash:

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

También vale la pena saber que “todas las funciones de ruido, excepto el ruido de Perlin y el ruido de convolución enrarecido, son aproximadamente en forma de banda. El ruido de Perlin es solo de banda débil, lo que puede conducir a problemas de distorsión y pérdida de detalles ”. 8 Además, el ruido de Perlin no tiene distribución de amplitud gaussiana. Es decir, los puntos de ruido no se dispersan sobre la base de una función gaussiana, que no consideraremos en este artículo. Hay muchas cosas en las que Perlin se siente muy cómodo, pero hay cosas en las que está muy débil. En la tabla a continuación 9 puede verlo usted mismo.



Ruido de Perlin en la práctica: implementaciones de GLSL


Entonces, hablemos del ruido de Perlin en GLSL. El ruido Perlin se puede usar como onda, como color difuso, como material difuso, como luz parpadeante o como manchas en una textura. Personalmente, lo usé en este ejemplo como un parpadeo de color.


Mientras escribo este artículo, estoy pensando en crear un complemento para After Effects que agregue la funcionalidad de ruido Perlin.

El ruido más simple de Perlin se puede crear 10 de la siguiente manera:

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

Sin embargo, esta es una versión renovada del ruido de Perlin, que se creó en 2002. Vaya a Gist para ver cómo se realiza el ruido clásico de Perlin.

Bueno, eso es todo por hoy. Una publicación corta, lo sé, y carece de contenido original, pero hasta ahora me he quedado sin ideas, porque todavía no he leído el renderizado en tiempo real . Este libro está lleno de conceptos e ideas para aprender y aprender. La amo


Paralelamente, estoy leyendo otro libro: Fundamentals of Computer Graphics . Estoy un poco atascado en el tema de las curvas implícitas, pero le pediré ayuda a mi pariente con doctorado en matemáticas.


Referencias


  • Una encuesta sobre las funciones de ruido de procedimiento, Computer Graphics Forum, Volumen 29 (2010), Número 8, pp 2379-2600
  • Ruido computacional eficiente, Journal of Graphics Tools Volumen 16, No. 2: 85-94

  1. Una encuesta, et al.
  2. flafla2.imtqy.com/2014/08/09/perlinnoise.html
  3. A. Lagaue y col.
  4. A. Lagae, et al.
  5. A. Lagae, et al.
  6. De flafla2.imtqy.com/2014/08/09/perlinnoise.html
  7. De Wikipedia
  8. A. Lagae, et al.
  9. Adaptado de A. Lagae, et al.
  10. gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83

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


All Articles