线性插值如何在经典的Perlin噪声中工作?

时间:2012-05-10 07:05:50

标签: javascript noise perlin-noise linear-interpolation

昨天我将经典的Perlin噪音(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);

你和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);

我的问题: 为什么Perlin以不同的方式使用lerp函数?

1 个答案:

答案 0 :(得分:3)

Here你可以从最初的Perlin演讲中找到一个Java applet,它非常清楚地解释了整个2D噪声计算过程。 perlin的噪声函数是连续的,因为在每个点(1D),它是两个“平滑”线性梯度的线性插值。 “平滑”来自s_curve函数,它只是hermite函数,实际上是余弦插值的近似值。但是,我会留下您的applet和其他演示文稿以获得更好的解释。

也许你也可以找到有趣的this project of mine:这是一个在html5画布上呈现Perlin和Simplex 2D噪音的javascript应用程序。查看源代码,了解这些和其他噪声函数的完整javascript实现。

希望有所帮助,再见!