不需要双重排列表的Perlin Noise实现

问题描述 投票:0回答:1

我看到的Perlin Noise的许多实现使置换表加倍,因为索引可能超出[0, 255]范围。

private static readonly int[] p;

static Perlin() {
    p = new int[512];
    for(int x=0;x<512;x++) {
        p[x] = permutation[x%256];
    }
}

private static readonly int[] 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
};

public double perlin(double x, double y, double z) {
    if(repeat > 0) {
        x = x%repeat;
        y = y%repeat;
        z = z%repeat;
    }

    // This means xi/yi/zi is in the range [0,255]
    int xi = (int)x & 255;
    int yi = (int)y & 255;
    int zi = (int)z & 255;
    double xf = x-(int)x;
    double yf = y-(int)y;
    double zf = z-(int)z;
    double u = fade(xf);
    double v = fade(yf);
    double w = fade(zf);

    // inc(xi) basically means xi + 1
    // thus we may be selecting permutation[255 + 1], which is out of range
    // hence we create a p[] array, that's double of permutation[] array.
    int aaa, aba, aab, abb, baa, bba, bab, bbb;
    aaa = p[p[p[    xi ]+    yi ]+    zi ];
    aba = p[p[p[    xi ]+inc(yi)]+    zi ];
    aab = p[p[p[    xi ]+    yi ]+inc(zi)];
    abb = p[p[p[    xi ]+inc(yi)]+inc(zi)];
    baa = p[p[p[inc(xi)]+    yi ]+    zi ];
    bba = p[p[p[inc(xi)]+inc(yi)]+    zi ];
    bab = p[p[p[inc(xi)]+    yi ]+inc(zi)];
    bbb = p[p[p[inc(xi)]+inc(yi)]+inc(zi)];

    double x1, x2, y1, y2;
    x1 = lerp(  grad (aaa, xf  , yf  , zf),
                grad (baa, xf-1, yf  , zf),
                u);
    x2 = lerp(  grad (aba, xf  , yf-1, zf),
                grad (bba, xf-1, yf-1, zf),
                  u);
    y1 = lerp(x1, x2, v);

    x1 = lerp(  grad (aab, xf  , yf  , zf-1),
                grad (bab, xf-1, yf  , zf-1),
                u);
    x2 = lerp(  grad (abb, xf  , yf-1, zf-1),
                grad (bbb, xf-1, yf-1, zf-1),
                u);
    y2 = lerp (x1, x2, v);

    return lerp (y1, y2, w);
}

但是,我看到one implementation只是将另一个数字添加到排列表中。这样就跳过了所有工作。

public static float Noise(float x, float y, float z)
{
    var X = Mathf.FloorToInt(x) & 0xff;
    var Y = Mathf.FloorToInt(y) & 0xff;
    var Z = Mathf.FloorToInt(z) & 0xff;
    x -= Mathf.Floor(x);
    y -= Mathf.Floor(y);
    z -= Mathf.Floor(z);
    var u = Fade(x);
    var v = Fade(y);
    var w = Fade(z);
    // This implementation doesn't create p[] array
    // It just repeated a number so that permutation has 257 items.
    // And cap the result so that we never select index beyond 256.
    var A  = (perm[X  ] + Y) & 0xff;
    var B  = (perm[X+1] + Y) & 0xff;
    var AA = (perm[A  ] + Z) & 0xff;
    var BA = (perm[B  ] + Z) & 0xff;
    var AB = (perm[A+1] + Z) & 0xff;
    var BB = (perm[B+1] + Z) & 0xff;
    return Lerp(w, Lerp(v, Lerp(u, Grad(perm[AA  ], x, y  , z  ), Grad(perm[BA  ], x-1, y  , z  )),
                           Lerp(u, Grad(perm[AB  ], x, y-1, z  ), Grad(perm[BB  ], x-1, y-1, z  ))),
                   Lerp(v, Lerp(u, Grad(perm[AA+1], x, y  , z-1), Grad(perm[BA+1], x-1, y  , z-1)),
                           Lerp(u, Grad(perm[AB+1], x, y-1, z-1), Grad(perm[BB+1], x-1, y-1, z-1))));
}

//...

static int[] perm = {
    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,
    151 // It just repeated a number at index 0
};

这是Perlin Noise的有效实现吗?

c# unity3d perlin-noise
1个回答
0
投票

这里是基本随机佩林噪声数的实现,您可以使用它(基于P5.js)

https://github.com/lucasteles/PerlinNoiseNet/blob/master/PerlinNoise/PerlinNoise.cs

© www.soinside.com 2019 - 2024. All rights reserved.