Наивная идея «шума»: накидать
в узлы сетки случайные значения
и интерполировать между ними.
Это value noise — и он сразу выдаёт себя: сквозь картинку проступает сетка, всё распадается на квадраты.
Перлин сделал хитрее. В узле лежит не число, а случайное направление — градиент, стрелка.
Значение в точке — это скалярные произведения этих стрелок на векторы «от угла к точке», плавно смешанные специальной кривой:
float n00 = dot(g00, p - c00); // стрелка · смещение
float n10 = dot(g10, p - c10); // ...для всех 4 углов клетки
float n01 = dot(g01, p - c01);
float n11 = dot(g11, p - c11);
vec2 f = fade(fract(p)); // гладкая кривая, НЕ линейная
float n = mix(mix(n00,n10,f.x), mix(n01,n11,f.x), f.y);
В узлах значение строго ноль — оттого ни «пятен» на решётке,
ни швов.
А главное: стрелки не бросаются заново, а считаются хешем от целых координат и сида. Тот же узел при том же сиде — та же стрелка. Всегда. Собственно, поэтому один seed в Minecraft рисует одинаковый мир у всех.
#мат_геймдев #МатРазбор #шейдеры #procgen
