Проблема білого шуму
Білий шум присвоює кожній точці простору повністю незалежне випадкове значення. Його спектр потужності є пласким — усі частоти роблять однаковий внесок. Природні текстури суттєво інші: основна частка їхньої потужності припадає на низькі частоти (великомасштабні риси), а на вищих частотах потужність спадає (дрібні деталі). Спектр потужності природних текстур приблизно слідує закону P(f) ~ 1/f² — це характерна ознака фрактальних, самоподібних структур.
Інтерпольований шум значень — розміщення випадкових значень у вузлах сітки з подальшою інтерполяцією між ними — забезпечує узгодженість у масштабі сітки, але демонструє помітні артефакти, вирівняні по сітці, коли частота збігається з кроком сітки. Шум Перліна вирішує цю проблему, використовуючи випадкові градієнти замість випадкових значень.
Градієнтний шум: інсайт Перліна
Класичний шум Перліна присвоює кожній цілочисловій точці сітки випадковий одиничний градієнтний вектор. Значення шуму в точці P обчислюється так:
- Знаходження оточуючих кутів сітки (4 у 2D, 8 у 3D)
- Для кожного кута обчислення скалярного добутку градієнта цього кута з вектором від кута до точки P
- Плавна інтерполяція цих скалярних добутків за допомогою функції згладжування (fade)
// Покращена функція згладжування (fade) Кена Перліна (2002)
// 6t^5 - 15t^4 + 10t^3 — нульові перша й друга похідні в 0 та 1
function fade(t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
// Скалярний добуток градієнта з вектором зміщення
function grad(hash, x, y) {
const h = hash & 3;
const u = h < 2 ? x : y;
const v = h < 2 ? y : x;
return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
}
Функція згладжування має критичне значення. Оригінальний шум Перліна використовував кубічну функцію 3t² − 2t³ (smoothstep), яка має нульову першу похідну в точках 0 і 1, але ненульову другу похідну — це створювало помітні розриви на картах нормалей і картах рельєфу (bump maps). Квінтична функція 2002 року 6t⁵ − 15t⁴ + 10t³ має нульові першу й другу похідні на кінцях інтервалу, забезпечуючи неперервність класу C² і усуваючи ці артефакти.
Використання градієнтів замість значень усуває смугастість, вирівняну по сітці, яка властива шуму значень. Побудова через скалярний добуток гарантує, що шум плавно проходить через нуль у кожній точці сітки (оскільки вектор зміщення там має нульову довжину), створюючи приємну властивість «переходу через нуль у вузлах ґратки», яка уникає проблем зі зміщенням, властивих інтерпольованому шуму значень.
Октави, стійкість (persistence) та фрактальний шум
Одна октава шуму Перліна має одну характерну частоту, яка визначається кроком сітки. Щоб створити багатомасштабну, фрактальноподібну текстуру, ми підсумовуємо кілька октав зі зростаючою частотою та спадаючою амплітудою:
function fbm(x, y, octaves, persistence, lacunarity) {
let value = 0;
let amplitude = 1.0;
let frequency = 1.0;
let maxValue = 0;
for (let i = 0; i < octaves; i++) {
value += perlin(x * frequency, y * frequency) * amplitude;
maxValue += amplitude;
amplitude *= persistence; // зазвичай 0.5
frequency *= lacunarity; // зазвичай 2.0
}
return value / maxValue; // нормалізація до [-1, 1]
}
При persistence = 0.5 і lacunarity = 2.0 кожна октава подвоює частоту та зменшує амплітуду вдвічі. Після N октав найдрібніші деталі стають у 2^N разів меншими за найгрубіші. Спектр потужності слідує закону P(f) ~ f^(-2·log₂(1/persistence)) — для persistence = 0.5 це дає P(f) ~ f⁻², що відповідає статистиці природних текстур.
Зміна persistence змінює характер текстури: висока persistence (0.7–0.9) дає виразні, контрастні текстури з підкресленими дрібними деталями. Низька persistence (0.2–0.4) дає гладкі, плавно хвилясті поверхні, де домінують грубі риси. Турбулентність використовує абсолютне значення кожної октави — |noise(x,y)| — створюючи гострі гребені та хмароподібні клубчасті форми.
Симплекс-шум: удосконалення Перліна 2001 року
Симплекс-шум Перліна 2001 року усуває дві слабкості оригінального алгоритму: обчислювальну складність (O(2^N) кутів сітки в N вимірах стає дорогим для 4D і вище) та напрямкові артефакти (квадратна/кубічна сітка має переважні напрямки).
Симплекс-шум використовує симплексну ґратку — найпростішу геометричну форму в N вимірах. У 2D симплекси — це рівносторонні трикутники (3 кути) замість квадратів (4 кути). У 3D — тетраедри (4 кути) замість кубів (8 кутів). У N вимірах — (N+1) кутів замість 2^N. Виграш у складності для шуму високої розмірності вражаючий: 4D-симплекс-шум потребує лише 5 обчислень градієнта проти 16 в оригінальному алгоритмі.
Симплексна ґратка також має кращу ізотропність — відстань від будь-якої внутрішньої точки до найближчого кута варіюється менше, ніж у квадратної ґратки, що зменшує напрямкове зміщення результату. Симплекс-шум став стандартом для високопродуктивних GPU-шейдерів та ігрових рушіїв.
Застосування: рельєф, хмари та системи частинок
Генерація рельєфу накладає октави з викривленням області (domain warping) — подаючи результат шуму назад як зміщення вхідних координат: height(p) = fbm(p + fbm(p)). Такий «викривлений» фрактальний шум створює звивисті долини та навислі скелі, характерні для реалістичних гір. Симуляція ерозії (гідравлічної та термічної) додатково вдосконалює рельєф, переміщуючи матеріал з ділянок з високим градієнтом до ділянок з низьким, загострюючи гребені та згладжуючи долини.
Анімований шум керує багатьма ефектами в симуляціях на цьому сайті. Турбулентність рідини використовує 3D- або 4D-шум (додаючи час як вимір), щоб генерувати просторово узгоджені збурення швидкості. Зміщення піщинок використовує 2D-шум, що прокручується в напрямку вітру. Ефект полярного сяйва використовує викривлений шум для характерних форм завіс.