Estoy jugando con Perlin Noise después de trabajar con Diamond Square. Seguí la implementación de Hugo Elias que básicamente realiza una serie de funciones con x, y como entrada para arrojar cada valor de coordenadas.
Mi código PHP está aquí :
Tengo dos preguntas:
¿Cómo uso el algoritmo para generar un mapa de altura en una matriz? No lo entendí completamente y simplemente porté a PHP el pseudocódigo, pero hice la última función (map_perlined) después de leer en alguna parte que el algoritmo "mágicamente" le da valores de transición para cada punto x, y dado (aparentemente, sin tener que leer su valores adyacentes), solo obtengo esto cuando lo uso como función aleatoriamt_rand(-100,100)/100;
Y esto cuando se usa el criptográfico: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
(que, por cierto, se puede implementar "tal cual" en PHP?):
En resumen, tres preguntas:
- ¿Es correcto mi código?
- ¿La función aleatoria se puede portar a PHP como se describe en el código? No arroja errores, pero los resultados no están ahí.
- ¿Cómo uso realmente el algoritmo?
ACTUALIZAR
Ok, hizo un puerto PHP del código que se muestra en el documento de Gustavson, y como dijo otro codificador, solo genera una octava. ¿Tiene algún otro sitio / documento / guía útil sobre cómo usar esto con los conceptos de octavas múltiples, amplitud, frecuencia, etc. para controlar la función de ruido? En el artículo de Gustavson solo muestra los resultados, no la implementación real del algoritmo, ¿tal vez me estoy perdiendo algo?
ACTUALIZACIÓN 2
@NATHAN
Hice algo como:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
for ($o = 0; $o < 8; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += SimplexNoise($i*$frequency, $j * $frequency) * $amplitude;
}
//$value = SimplexNoise($i, $j) + 0.5 * SimplexNoise($i, $j) + 0.25 * SimplexNoise($i, $j);
$this->mapArray[$i][$j] = new Cell($value);
Y después de normalizar los valores a 0..1, obtengo un mapa de altura bastante aburrido como:
¿Cómo siembro el mapa? ¿Quizás lo que necesito implementar es la versión 3d con el tercer valor de una altura aleatoria? Pero si es así, tendría que averiguar para tener en cuenta los valores vecinos, que terminaría con algo así como un algoritmo de diamante cuadrado, exactamente lo que no quiero hacer.
ACTUALIZACIÓN 3
Más trabajo de Perlin. Todavía tengo que encontrar una manera de guiar el ruido a mis resultados. Comprueba estas octavas y el resultado final:
Octava I a IV
Resumió
Cada octava es más o menos lo mismo. Revisa el código:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
$value = 0;
for ($o = 0; $o < 4; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += improved_noise($i*$frequency, $j*$frequency, 0.5)*$amplitude;
}
$this->map[$i][$j] = new Cell($value);
Los resultados están normalizados. ¿Qué utilizarías para tener una fuerte influencia en el desarrollo del ruido? Veo ejemplos en los que cambiar la amplitud da superficies suaves o rugosas, pero incluso si doy una gran amplitud, veo poca diferencia.
Respuestas:
Lo que implementaste no es ruido de Perlin. No estoy seguro de por qué Hugo Elias dice que sí, pero está confundido. Aquí está la implementación de referencia de Ken Perlin. En realidad, no llama a ningún generador externo de números aleatorios, pero usa una función hash incorporada para producir los vectores de gradiente pseudoaleatorio.
Tenga en cuenta también que el ruido Perlin consta de solo una octava. Resumir varias octavas (instancias escaladas de la función de ruido), como sugiere Hugo Elias, es una técnica útil, pero no parte del ruido de Perlin. Lo que se obtiene al hacer eso se llama ruido fractal, a veces "ruido browniano fractal" (debido a la supuesta similitud con el movimiento browniano).
Si desea comprender geométricamente lo que está haciendo el algoritmo, pruebe este documento . Se trata de un tipo diferente de ruido llamado "ruido simplex", pero también incluye una explicación del ruido clásico de Perlin. Por cierto, el ruido simple también fue inventado por Perlin y se supone que es una mejora sobre su ruido clásico, por lo que podría intentar implementarlo también si está interesado en jugar con funciones de ruido.
fuente
Ese es un error común. Lo que Hugo Elias llama ruido "Perlin" es, de hecho, ruido fractal o rosado. Para comprender mejor qué es el ruido de Perlin, puede leer el artículo de Perlin vinculado en la respuesta de Nathan Reed, o los documentos de libnoise (existe el mismo error: el ruido de Perlin es lo que llaman ruido de degradado), o los documentos de CoherentNoise .
Ahora, para responder realmente a su pregunta: no obtuvo el resultado esperado porque la frecuencia de ruido es demasiado alta. Sus frecuencias comienzan con 1 y aumentan, lo que significa que cada píxel en el mapa resultante tiene un valor aleatorio. Para ver una estructura más fina del mapa, debe "acercar" el ruido. Realmente no hablo PHP, pero supongo que el código debería verse así:
Es decir, usted "extiende" un período de ruido sobre todo el mapa. Por supuesto, puede usar otros coeficientes, solo pruebe diferentes, vea qué sucede.
fuente