单纯形噪声范围太小

Simplex noise range too small

我正在使用以下单纯形噪声的实现(附录 B): https://www.csee.umbc.edu/~olano/s2002c36/ch02.pdf

这是 Ken Perlin 自己写的。

PDF 中的代码是用 JAVA 编写的,但我已将其翻译成 C++。这是我的代码(您也可以在 C++ Shell 上 运行):

#include <iostream>
#include <string>
#include <cmath>

int i,j,k, A[3] = {0,0,0};
float u,v,w;

int T[8] = {0x15,0x38,0x32,0x2c,0x0d,0x13,0x07,0x2a};
int b(int N, int B) { return N>>B & 1; }
int b(int i, int j, int k, int B) { return T[b(i,B)<<2 | b(j,B)<<1 | b(k,B)]; }

int shuffle(int i, int j, int k) {
    return b(i,j,k,0) + b(j,k,i,1) + b(k,i,j,2) + b(i,j,k,3) +
    b(j,k,i,4) + b(k,i,j,5) + b(i,j,k,6) + b(j,k,i,7) ;
}

float K(int a) {
    float s = (A[0]+A[1]+A[2])/6.;
    float x = u-A[0]+s, y = v-A[1]+s, z = w-A[2]+s, t = .6-x*x-y*y-z*z;
    int h = shuffle(i+A[0],j+A[1],k+A[2]);
    A[a]++;
    if (t < 0)
    return 0;
    int b5 = h>>5 & 1, b4 = h>>4 & 1, b3 = h>>3 & 1, b2= h>>2 & 1, b = h & 3;
    float p = b==1?x:b==2?y:z, q = b==1?y:b==2?z:x, r = b==1?z:b==2?x:y;
    p = (b5==b3 ? -p : p); q = (b5==b4 ? -q : q); r = (b5!=(b4^b3) ? -r : r);
    t *= t;
    return 8 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));
}

float noise(float x, float y, float z) {
    float s = (x+y+z)/3;
    i=(int)floorf(x+s); j=(int)floorf(y+s); k=(int)floorf(z+s);
    s = (i+j+k)/6.; u = x-i+s; v = y-j+s; w = z-k+s;
    A[0]=A[1]=A[2]=0;
    int hi = u>=w ? u>=v ? 0 : 1 : v>=w ? 1 : 2;
    int lo = u< w ? u< v ? 0 : 1 : v< w ? 1 : 2;
    return K(hi) + K(3-hi-lo) + K(lo) + K(0);
}

int main() {
    float scale = 0.0007f;
    float min = 1.0f;
    float max = -1.0f;
    for (int x = 0; x < 100000; x++) {
        float v = noise(x * scale, 0.0f, 0.0f);
        if (v > max) max = v;
        if (v < min) min = v;
    }
    printf("min = %f\r\n", min);
    printf("max = %f\r\n", max);
}

问题是,调用噪声函数只给我 -0.3 和 0.3 之间的值。

我期望得到介于 -1.0 和 1.0 之间的值。

这个特定的实现有问题吗?

Obs:我没有标准化输出,也没有计算任何额外的八度音阶。

我想出了一个解决方案,但我确定这不是正确的解决方法。

我改变了这个:

return 8 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));

为此:

return 26 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));

现在我得到了一个不错的输出。