El ruido de Perlin es un tipo de ruido de gradiente desarrollado por Ken Perlin en 1983. Tiene muchos usos, entre los que se incluyen, entre otros: generar terreno de manera procedimental , aplicar cambios pseudoaleatorios a una variable y ayudar en la creación de texturas de imágenes . Se implementa con mayor frecuencia en dos, tres o cuatro dimensiones , pero se puede definir para cualquier número de dimensiones.
Ken Perlin desarrolló el ruido Perlin en 1983 como resultado de su frustración con el aspecto "similar a una máquina" de las imágenes generadas por computadora (CGI) en ese momento. [1] Describió formalmente sus hallazgos en un artículo de SIGGRAPH en 1985 llamado "Un sintetizador de imágenes". [2] Lo desarrolló después de trabajar en la película de ciencia ficción animada por computadora de Disney Tron (1982) para la compañía de animación Mathematical Applications Group (MAGI). [3] En 1997, Perlin recibió un Premio de la Academia por Logros Técnicos por crear el algoritmo, cuya cita decía: [4] [5] [6] [7]
A Ken Perlin por el desarrollo de Perlin Noise, una técnica utilizada para producir texturas de apariencia natural en superficies generadas por computadora para efectos visuales cinematográficos. El desarrollo de Perlin Noise ha permitido a los artistas de gráficos por computadora representar mejor la complejidad de los fenómenos naturales en efectos visuales para la industria cinematográfica.
Perlin no solicitó ninguna patente para el algoritmo, pero en 2001 se le concedió una patente para el uso de implementaciones 3D+ de ruido simplex para la síntesis de texturas . El ruido simplex tiene el mismo propósito, pero utiliza una cuadrícula de relleno de espacio más simple. El ruido simplex alivia algunos de los problemas con el "ruido clásico" de Perlin, entre ellos la complejidad computacional y los artefactos direccionales visualmente significativos. [8]
El ruido Perlin es una textura primitiva procedimental, un tipo de ruido de gradiente utilizado por los artistas de efectos visuales para aumentar la apariencia de realismo en gráficos de computadora . La función tiene una apariencia pseudoaleatoria , pero todos sus detalles visuales son del mismo tamaño. Esta propiedad le permite ser fácilmente controlable; se pueden insertar múltiples copias escaladas del ruido Perlin en expresiones matemáticas para crear una gran variedad de texturas procedimentales. Las texturas sintéticas que utilizan ruido Perlin se utilizan a menudo en CGI para hacer que los elementos visuales generados por computadora, como superficies de objetos, fuego, humo o nubes, parezcan más naturales, imitando la apariencia aleatoria controlada de las texturas en la naturaleza.
También se utiliza con frecuencia para generar texturas cuando la memoria es extremadamente limitada, como en las demostraciones . Sus sucesores, como el ruido fractal y el ruido simplex , se han vuelto casi omnipresentes en las unidades de procesamiento gráfico, tanto para gráficos en tiempo real como para texturas procedimentales en tiempo no real en todo tipo de gráficos de computadora.
Se utiliza con frecuencia en videojuegos para generar un terreno de forma procedimental que parezca natural. Este éxito se debe en parte a la estructuración jerárquica del ruido de Perlin, que imita las estructuras jerárquicas naturales y, por lo tanto, también ha resultado útil en aplicaciones de ciencias ambientales. [9]
El ruido de Perlin se implementa más comúnmente como una función bidimensional, tridimensional o cuatridimensional , pero se puede definir para cualquier número de dimensiones. Una implementación generalmente implica tres pasos: definir una cuadrícula de vectores de gradiente aleatorios, calcular el producto escalar entre los vectores de gradiente y sus desplazamientos, e interpolación entre estos valores. [7]
Defina una cuadrícula n -dimensional donde cada intersección de cuadrícula tiene asociado un vector de gradiente de longitud unitaria aleatorio fijo n -dimensional, excepto en el caso unidimensional donde los gradientes son escalares aleatorios entre −1 y 1.
Para calcular el valor de cualquier punto candidato, primero encuentre la celda de la cuadrícula única en la que se encuentra el punto. Luego, identifique las 2 n esquinas de esa celda y sus vectores de gradiente asociados. A continuación, para cada esquina, calcule un vector de desplazamiento. Un vector de desplazamiento es un vector de desplazamiento desde esa esquina hasta el punto candidato.
Para cada esquina, calculamos el producto escalar entre su vector de gradiente y el vector de desplazamiento hasta el punto candidato. Este producto escalar será cero si el punto candidato está exactamente en la esquina de la cuadrícula.
Tenga en cuenta que la influencia de un vector de gradiente aumenta con la distancia, lo que se puede evitar normalizando primero el vector de desplazamiento a una longitud de 1. Esto introduciría cambios notables, excepto que la distancia se tiene en cuenta en el siguiente paso de interpolación. Sin embargo, la normalización del vector de desplazamiento no es una práctica habitual.
Para un punto en una cuadrícula bidimensional, esto requerirá el cálculo de cuatro vectores de desplazamiento y productos escalares, mientras que en tres dimensiones requerirá ocho vectores de desplazamiento y ocho productos escalares. En general, el algoritmo tiene una complejidad de O (2 n ) en n dimensiones.
El paso final es la interpolación entre los 2 n productos escalares. La interpolación se realiza utilizando una función que tiene una primera derivada cero (y posiblemente también una segunda derivada) en los 2 n nodos de la cuadrícula. Por lo tanto, en los puntos cercanos a los nodos de la cuadrícula, la salida se aproximará al producto escalar del vector de gradiente del nodo y el vector de desplazamiento hacia el nodo. Esto significa que la función de ruido pasará por 0 en cada nodo, lo que le da al ruido de Perlin su aspecto característico.
Si n = 1 , un ejemplo de una función que interpola entre el valor a 0 en el nodo de cuadrícula 0 y el valor a 1 en el nodo de cuadrícula 1 es
donde se utilizó la función smoothstep .
Las funciones de ruido para uso en gráficos de computadora generalmente producen valores en el rango [–1.0, 1.0] y se pueden escalar en consecuencia.
La siguiente es una implementación bidimensional del ruido Perlin clásico, escrita en C.
La implementación de referencia original de Perlin tenía diferencias importantes [ cita requerida ] :
#include <matemática.h> /* Función para interpolar linealmente entre a0 y a1 * El peso w debe estar en el rango [0.0, 1.0] */ float interpolate ( float a0 , float a1 , float w ) { /* // Es posible que desees realizar una restricción insertando: * if (0.0 > w) return a0; * if (1.0 < w) return a1; */ return ( a1 - a0 ) * w + a0 ; /* // Usa esta interpolación cúbica [[Smoothstep]] en su lugar, para una apariencia suave: * return (a1 - a0) * (3.0 - w * 2.0) * w * w + a0; * * // Usa [[Smootherstep]] para un resultado aún más suave con una segunda derivada igual a cero en los límites: * return (a1 - a0) * ((w * (w * 6.0 - 15.0) + 10.0) * w * w * w) + a0; */ } typedef struct { float x , y ; } vector2 ; /* Crear vector de dirección pseudoaleatorio */ vector2 randomGradient ( int ix , int iy ) { // Sin gradientes precalculados, lo que significa que esto funciona para cualquier número de coordenadas de cuadrícula const unsigned w = 8 * sizeof ( unsigned ); const unsigned s = w / 2 ; // ancho de rotación unsigned a = ix , b = iy ; a *= 3284157443 ; b ^= a << s | a >> w - s ; b *= 1911520717 ; a ^= b << s | b >> w - s ; a *= 2048419325 ; float random = a * ( 3.14159265 / ~ ( ~ 0u >> 1 )); // en [0, 2*Pi] vector2 v ; v . x = cos ( random ); v . y = sin ( aleatorio ); devuelve v ; } // Calcula el producto escalar de los vectores de distancia y gradiente. float dotGridGradient ( int ix , int iy , float x , float y ) { // Obtener el gradiente a partir de coordenadas enteras vector2 gradient = randomGradient ( ix , iy ); // Calcular el vector de distancia float dx = x - ( float ) ix ; float dy = y - ( float ) iy ; // Calcular el retorno del producto escalar ( dx * gradient . x + dy * gradient . y ); } // Calcular el ruido de Perlin en las coordenadas x, y float perlin ( float x , float y ) { // Determinar las coordenadas de la celda de la cuadrícula int x0 = ( int ) floor ( x ); int x1 = x0 + 1 ; int y0 = ( int ) floor ( y ); int y1 = y0 + 1 ; // Determinar los pesos de interpolación // También se puede utilizar un polinomio de orden superior/curva s aquí float sx = x - ( float ) x0 ; float sy = y - ( float ) y0 ; // Interpolar entre gradientes de puntos de la cuadrícula float n0 , n1 , ix0 , ix1 , value ; n0 = dotGridGradient ( x0 , y0 , x , y ); n1 = dotGridGradient ( x1 , y0 , x , y ); ix0 = interpolar ( n0 , n1 , sx ); n0 = dotGridGradient ( x0 , y1 , x , y ); n1 = dotGridGradient ( x1 , y1 , x , y ); ix1 = interpolar ( n0 , n1 , sx ); valor = interpolar ( ix0 , ix1 , sy ); valor de retorno ; // Regresará en el rango -1 a 1. Para que esté en el rango 0 a 1, multiplique por 0,5 y agregue 0,5 }
Muchas implementaciones de ruido de Perlin utilizan el mismo conjunto de permutaciones que Ken Perlin utilizó en su implementación original. [10] Esa implementación es la siguiente:
int permutación [] = { 151 , 160 , 137 , 91 , 90 , 15 , 131 , 13 , 201 , 95 , 96 , 53 , 194 , 233 , 7 , 225 , 140 , 36 , 103 , 30 , 69 , 142 , 8 , 99 , 37 , 240 , 21 , 10 , 23 , 190 , 6 , 148 , 247 , 120 , 234 , 75 , 0 , 26 , 197 , 62 , 94 , 252 , 219 , 203 , 117 , 35 , 11 , 32 , 57 , 177 , 33 , 88 , 237 , 149 , 56 , 87 , 174 , 20 , 125 , 136 , 171 , 168 , 68 , 175 , 74 , 65 , 71 , 134 , 139 , 48 , 27 , 166 , 77 , 146 , 158 , 231 , 83 , 111 , 229 , 122 , 60 , 211 , 133 , 230 , 220 , 105 , 92 41 , 55 , 46 , 245 , 40 , 244 , 102 , 143 , 54 , 65 , 25 , 63 , 161 , 1 , 216 , 80 , 73 , 209 , 76 , 132 , 187 , 208 , 89 , 18 , 169 , 200 , 196 , 135 , 130 , 116 , 188 , 159 , 86 , 164 , 100 , 109 , 198 , 173 , 186 , 3 , 64 , 52 , 217 , 226 , 250 , 124 , 123 , 5 , 202 , 38 , 147 , 118 , 126 , 255 , 82 , 85 , 212 , 207 , 206 , 59 , 227 , 47 , 16 , 58 , 17 , 182 , 189 , 28 , 42 , 223 , 183 , 170 , 213 , 119 , 248 , 152 , 2 , 44 , 154 , 163 , 70 , 221 , 153 , 101 , 155 , 167 , 43 , 172 , 9 , 129 , 22 , 39 , 253 , 19 , 98 , 108 , 110 , 79 , 113 , 224 , 232 , 178 , 185 , 112 , 104 , 218 , 246 , 97 , 228 , 251 , 34 , 242 , 193 , 238 , 210 , 144 , 12 , 191 , 179 , 162 , 241 , 81 , 51 , 145 , 235 , 249 , 14 , 239 , 107 , 49 , 192 , 214 , 31 , 181 , 9 , 106 , 157 , 184 , 84 , 204 , 176 , 115 , 121 , 50 , 45 , 127 , 4 , 150 , 254 , 138 , 236 , 205 , 93 , 222 , 114 , 67 , 29 , 24 , 72 , 243 , 141 , 128 , 195 , 78 , 66 , 215 , 61 , 156 , 180 };
Esta permutación específica no es absolutamente necesaria, aunque sí requiere una matriz aleatoria de números enteros del 0 al 255. Si se crea una nueva tabla de permutación, se debe tener cuidado para asegurar una distribución uniforme de los valores. [11]
Para cada evaluación de la función de ruido, el producto escalar de los vectores de posición y gradiente debe evaluarse en cada nodo de la celda de la cuadrícula que lo contiene. Por lo tanto, el ruido Perlin se escala con una complejidad O (2 n ) para n dimensiones. Las alternativas al ruido Perlin que producen resultados similares con una escala de complejidad mejorada incluyen el ruido simplex y el ruido OpenSimplex .
{{cite web}}
: CS1 maint: bot: estado de URL original desconocido ( enlace )de la 'función de ruido coherente' de Ken Perlin