Вчера я портировал классический шум Перлина (src: http://mrl.nyu.edu/~perlin/doc/oscar.html#noise) на JavaScript. Странно, что созданный шум сильно отличается от ожидаемого. Классический шум Perlin использует линейную интерполяцию/lerp, но шум является гладким, а не окантованным. Это больше похоже на косинусную интерполяцию. Кажется, что Perlin использует функцию lerp по-другому.Как работает линейная интерполяция в классическом шуме Perlin?
Вот исходный код портирована на 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);
Мой вопрос: Почему Перлин использовать функцию Lerp так иначе?
Я не понимаю вашу проблему. У вас есть 2 сценария JS, один работает, почему бы не использовать его. –
Перлин-шум должен быть непрерывным и иметь последовательную шкалу характеристик. Более «зубчатый» шум создается путем добавления дополнительных итераций высокочастотного шума. – Alnitak
Это проблема понимания, а не проблема программирования. Код работает отлично, но я не понимаю, почему Perlin использует что-то вроде линейной интерполяции, если созданный шум явно не выглядит линейно интерполированным. Разве это не нужно? – Pipo