Pregunta

Estoy tratando de crear una función de ruido Perlin / Simplex / Value en JavaScript que dará resultados similares a los siguientes:

enter image description here(Nota: esta imagen ya ha tenido un tensor aplicado. Lo quiero sin el pasajero).

He estado buscando en todo Internet durante 2 días. Hay muchos enlaces que explican el ruido y mucho código, pero ninguno en JavaScript, y cada vez que trato de convertirlo, obtengo resultados extraños. Estos son algunos de mis atemps:

Creo que parte del problema podría derivarse del uso de los operadores bit a JavaScript, donde es difícil hacer cumplir el tipo de un número.

Lo que estoy buscando es un ejemplo de ruido de JavaScript (cualquier tipo).

También estaría dispuesto a otorgar una recompensa para cualquier información relacionada con los parámetros que podrían conducir a un patrón similar a la imagen que publiqué (antes del umbral) o cualquier consejo de optimización, ya que necesitaré que esto se ejecute lo más rápido posible ( en JavaScript de todos modos).

¿Fue útil?

Solución 2

Usaré el código que se encuentra en esta esencia.

Otros consejos

Hice algo como esto hace un tiempo, sin embargo, usé el desplazamiento del punto medio. Si puede averiguar qué está pasando, podría ser útil

http://www.somthinghitme.com/projects/canvasterrain/

También esta aquí

https://github.com/loktar00/javascript-canvas-terrain-generator

Y aquí hay un violín con solo la parte de ruido implementada con una iluminación genial,

http://jsfiddle.net/loktar/4qaxz/

Buena suerte :).

Sé que esto es bastante viejo, pero tal vez aún puede ser útil para otra persona. He creado una aplicación JavaScript que hace que Perlin y Simplex ruido a un lienzo HTML5, échale un vistazo aquí: http://lencinhaus.github.com/canvas-noise

La aplicación permite ajustar todos los parámetros involucrados en el cálculo y la representación de ruido y guardar la textura resultante. También agrega los parámetros a la URL, para que se pueda compartir. Por ejemplo, esta configuración produce una textura muy similar a la que mostró.

¡Espero que ayude!

Esto es el código con el que terminé para el ruido 2D / 3D Perlin. Tenga en cuenta que utiliza la sintaxis del módulo AMD de Requirjs, pero puede quitarla si no está usando un cargador AMD.

define(
    [],
    function()
    {
        function fade(t)
        {
            return t * t * t * (t * (t * 6 - 15) + 10);
        }

        function lerp(t, a, b)
        {
            return a + t * (b - a);
        }

        function grad(hash, x, y, z)
        {
            // Convert lo 4 bits of hash code into 12 gradient directions.
            var h = hash & 15,
                u = h < 8 ? x : y,
                v = h < 4 ? y : h == 12 || h == 14 ? x : z;
            return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
        }

        function scale(n)
        {
            return (1 + n) / 2;
        }

        var p = new Array(512);

        var permutation = [
            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, 165, 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, 199, 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
        ];

        for (var i = 0; i < 256; i++) {
            p[256 + i] = p[i] = permutation[i];
        }

        return {
            /** Returns a number between 0 and 1. */
            noise3d: function(x, y, z)
            {
                // Find unit cube that contains point.
                var X = Math.floor(x) & 255,
                    Y = Math.floor(y) & 255,
                    Z = Math.floor(z) & 255;
                // Find relative x,y,z of point in cube.
                x -= Math.floor(x);
                y -= Math.floor(y);
                z -= Math.floor(z);
                // Compute fade curves for each of x,y,z.
                var u = fade(x),
                    v = fade(y),
                    w = fade(z);
                // Hash coordinates of the corners.
                var A = p[X    ] + Y, AA = p[A] + Z, AB = p[A + 1] + Z,
                    B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z;

                // Add blended results from 8 corners of cube.
                return scale(
                    lerp(
                        w,
                        lerp(
                            v,
                            lerp(
                                u,
                                grad(p[AA], x, y, z),
                                grad(p[BA], x - 1, y, z)
                            ),
                            lerp(
                                u,
                                grad(p[AB], x, y - 1, z),
                                grad(p[BB], x - 1, y - 1, z)
                            )
                        ),
                        lerp(
                            v,
                            lerp(
                                u,
                                grad(p[AA + 1], x, y, z - 1),
                                grad(p[BA + 1], x - 1, y, z - 1)
                            ),
                            lerp(
                                u,
                                grad(p[AB + 1], x, y - 1, z - 1),
                                grad(p[BB + 1], x - 1, y - 1, z - 1)
                            )
                        )
                    )
                );
            },

            /** Returns a number between 0 and 1. */
            noise2d: function(x, y)
            {
                // Find unit square that contains point.
                var X = Math.floor(x) & 255,
                    Y = Math.floor(y) & 255;
                // Find relative x,y of point in square.
                x -= Math.floor(x);
                y -= Math.floor(y);
                // Compute fade curves for each of x,y.
                var u = fade(x),
                    v = fade(y);
                // Hash coordinates of the corners.
                var A = p[X    ] + Y, AA = p[A], AB = p[A + 1],
                    B = p[X + 1] + Y, BA = p[B], BB = p[B + 1];

                // Add blended results from the corners.
                return scale(
                    lerp(
                        v,
                        lerp(
                            u,
                            grad(p[AA], x, y, 0),
                            grad(p[BA], x - 1, y, 0)
                        ),
                        lerp(
                            u,
                            grad(p[AB], x, y - 1, 0),
                            grad(p[BB], x - 1, y - 1, 0)
                        )
                    )
                );
            }
        };
    }
);

Se me ocurrió esta solución que dio mejores resultados para mi caso de uso:

http://asserttrue.blogspot.com/2011/12/perlin-noise-in-javascript_31.html

Está usando una gran matriz de permutación:

var permutation = [ 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,165,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,199,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
];

Úselo como:

pn = PerlinNoise()
n = pn.noise( random_x, random_y, .8 )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top