2

昨天我将经典的 Perlin 噪声(源代码: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 之前的点和 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 函数的方式如此不同?

4

1 回答 1

3

在这里,您可以从 Perlin 的原始演讲中找到一个 Java 小程序,它非常清楚地解释了整个 2D 噪声计算过程。perlin 的噪声函数是连续的,因为在每个点(在一维中),它是两个“平滑”线性梯度的线性插值。“平滑”来自 s_curve 函数,它只是简单的 Hermite 函数,实际上是余弦插值的近似值。但是,我将把您留给小程序和演示文稿的其余部分以获得更好的解释。

也许你也可以发现我的这个项目很有趣:它是一个在 html5 画布上呈现 Perlin 和 Simplex 2D 噪声的 javascript 应用程序。查看源代码以获取这些和其他噪声函数的完整 javascript 实现。

希望对你有帮助,再见!

于 2013-03-22T01:30:44.403 回答