2012-05-10 42 views
2

昨天我将经典的柏林噪声(src:http://mrl.nyu.edu/~perlin/doc/oscar.html#noise)移植到JavaScript中。奇怪的是,生成的噪音看起来与我所期望的大不相同。经典的Perlin噪声使用线性插值/ lerp,但噪音平滑而不是边缘。它看起来更像是余弦插值。 看来Perlin以不同的方式使用lerp函数。线性插值在典型柏林噪声中如何工作?

这里是原代码移植到JavaScript的(用帆布图片): http://jsfiddle.net/fDTbv/

这是最有趣的部分:

t = vec[0] + N; 
bx0 = Math.floor(t) & BM; 
bx1 = (bx0+1) & BM; 
rx0 = t - Math.floor(t); 
rx1 = rx0 - 1.; 

sx = s_curve(rx0); 

u = rx0 * g1[ p[ bx0 ] ]; 
v = rx1 * g1[ p[ bx1 ] ]; 

return lerp(sx, u, v); 

u和v随时改变。为什么?不应该是u和v代表之前的点,sx之后的点也不会改变?

改变了代码到“我的预期”,它会怎样看:http://jsfiddle.net/8Xv8G/

而且有趣的部分:

bx0 = Math.floor(x) & BM; 
bx1 = (bx0+1) & BM; 

u = g1[ p[ bx0 ] ]; 
v = g1[ p[ bx1 ] ]; 

return lerp(x - Math.floor(x), u, v); 

我的问题: 为什么培林采用线性插值功能,所以不同?

+0

我不明白你的问题。你有两个JS脚本,一个是可行的,为什么不使用那个。 –

+0

Perlin噪声应该是连续的并且具有一致的特征尺度。通过增加额外的更高频率噪声迭代产生更多的“锯齿状”噪声。 – Alnitak

+0

这更多的是理解问题而不是编程问题。代码工作正常,但我不明白为什么Perlin使用类似线性插值的东西,如果生成的噪声显然不是线性插值的。这不是没有必要吗? – Pipo

回答

3

Here你可以从Perlin的原话中找到一个Java applet,它非常清楚地解释了整个2D噪声计算过程。珀林的噪声函数是连续的,因为在每个点(在1D),它是两个“平滑”线性梯度的线性插值。 “平滑”来自s_curve函数,它仅仅是埃尔米特函数,它实际上是余弦插值的近似值。不过,我会留给你小程序和演示文稿的其余部分,以获得更好的解释。

也许你还可以找到this project of mine有趣的是:它是一个javascript应用程序,它可以在html5画布上呈现Perlin和Simplex 2D噪声。查看完整的JavaScript实现这些和其他噪声功能的来源。

希望有所帮助,再见!

+0

感谢您的分享。 – Pipo