سؤال

Yesterday I ported the classic Perlin noise (src: http://mrl.nyu.edu/~perlin/doc/oscar.html#noise) to JavaScript. Strangely the generated noise looks a lot different from what I've expected. The classic Perlin noise uses linear interpolation/lerp, but the noise is smooth instead of edged. It looks more like cosine interpolation. It seems Perlin uses the lerp function in a different way.

Here is the original code ported to JavaScript (with canvas picture): http://jsfiddle.net/fDTbv/

This is the interesting part:

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 and v always change. Why? Shouldn't be u and v represent the point before and the point after sx and therefor don't change?

I changed the code to "what I expected" how it would look: http://jsfiddle.net/8Xv8G/

And the interesting part:

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

My question: Why does Perlin use the lerp function so differently?

هل كانت مفيدة؟

المحلول

Here you can find a Java applet from the original Perlin's talk that explains the whole 2D noise computation process very clearly. The perlin's noise function is continuous because, at each point (in 1D), it is the linear interpolation of two "smoothed" linear gradients. The "smoothing" comes from the s_curve function, which is simply the hermite function, which in fact is an approximation of cosine interpolation. However, I'll leave you to the applet and rest of the presentation for a better explanation.

Maybe you can also find this project of mine interesting: it's a javascript app that renders Perlin and Simplex 2D noise on an html5 canvas. Check out the source for a full javascript implementation of those and other noise functions.

Hope that helps, bye!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top