20 Stimmen

JavaScript Simplex/Perlin-Rauschen

Ich versuche, eine Perlin-/Simplex-/Wertrauschfunktion in JavaScript zu erstellen, die ähnliche Ergebnisse wie die folgenden liefert:

enter image description here (Hinweis: Auf dieses Bild wurde bereits ein Schwellenwert angewendet. Ich möchte es ohne den Schwellenwert).

Ich habe jetzt 2 Tage lang das ganze Internet durchforstet. Es gibt jede Menge Links, die Rauschen erklären, und eine Menge Code, aber keinen in JavaScript, und immer wenn ich versuche, es zu konvertieren, erhalte ich seltsame Ergebnisse. Hier sind einige meiner Versuche:

Ich denke, ein Teil des Problems könnte von der Verwendung der bitweisen Operatoren in JavaScript herrühren, wo es schwierig ist, den Typ einer Zahl zu erzwingen.

Was ich suche, ist ein Beispiel für funktionierendes JavaScript-Rauschen (egal welcher Art).

Ich wäre auch bereit, ein Kopfgeld für Informationen zu den Parametern zu zahlen, die zu einem ähnlichen Muster führen könnten wie das Bild, das ich gepostet habe (vor dem Schwellenwert), oder für Optimierungstipps, da das Ganze so schnell wie möglich laufen muss (in JavaScript).

0 Stimmen

Ich werde den Code verwenden, der auf dieser Gist.

6voto

lencinhaus Punkte 3165

Ich weiß, dass dieser Artikel schon ziemlich alt ist, aber vielleicht kann er noch jemandem nützlich sein. Ich habe eine Javascript-App gebaut, die Perlin- und Simplex-Rauschen auf eine HTML5-Leinwand überträgt, schauen Sie sich das hier an: http://lencinhaus.github.io/canvas-noise

Mit der App können Sie alle Parameter für die Rauschberechnung und das Rendering einstellen und die resultierende Textur speichern. Außerdem fügt sie die Parameter zur URL hinzu, so dass sie weitergegeben werden kann. Zum Beispiel, diese Konfiguration erzeugt eine Textur, die der von Ihnen angegebenen sehr ähnlich ist.

0 Stimmen

Könnten Sie den entsprechenden Code in Ihrer Antwort einfügen? Der Link ist schon lange tot und die Antwort ist nicht mehr hilfreich, es sei denn, der Link wird aktualisiert oder der Code wird der Antwort hinzugefügt.

4voto

Drew Noakes Punkte 282438

Hier ist der Code, den ich für 2D/3D-Perlin-Rauschen entwickelt habe. Beachten Sie, dass es RequireJS AMD-Modul-Syntax verwendet, aber Sie können, dass Streifen weg, wenn Sie nicht mit einem AMD-Loader sind.

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

1voto

Evhz Punkte 8080

Ich habe diese Lösung gefunden, die für meinen Anwendungsfall bessere Ergebnisse liefert:

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

Es wird eine große Permutationsmatrix verwendet:

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
];

Verwenden Sie es als:

pn = PerlinNoise()
n = pn.noise( random_x, random_y, .8 )

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X