我正在使用以下单纯形噪声实现(附录B): https://www.csee.umbc.edu/~olano/s2002c36/ch02.pdf
这是肯·佩林本人写的。
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);
}
问题是,调用noise函数只会给我-0.3到0.3之间的值。
我希望得到的值介于-1.0和1.0之间。
此特定实现是否存在问题?
Obs:我没有对输出进行规范化,也没有计算任何额外的八度。
答案 0 :(得分:0)
我想出了一个解决方案,我确定这不是正确的方法。
我更改了此内容
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));
现在我得到了很好的输出。