Cztery gradienty, cztery iloczyny skalarne, jedna funkcja wygładzająca, dwie interpolacje liniowe — i jedna, konkretna liczba. Ten rozdział rozpisuje to tak, żebyś mógł policzyć własny punkt na kartce i porównać z tym, co dostał komputer.
TL;DR
Dla punktu P w komórce siatki: policz 4 iloczyny skalarne (gradient węzła · wektor odległości do P), po jednym na narożnik.
Wygładź współrzędne P funkcją „fade” (nie liniowo!) — to eliminuje widoczne krawędzie komórek.
Zinterpoluj (biliniowo, Rozdział 9) cztery iloczyny skalarne, używając wygładzonych współrzędnych jako wag.
Pass: Wzór
Cztery kroki algorytmu
1) nᵢⱼ = gradientᵢⱼ · (P − węzełᵢⱼ), dla i,j ∈ {0,1} 2) u = fade(Px − ⌊Px⌋), v = fade(Py − ⌊Py⌋) 3) nx₀ = lerp(n₀₀, n₁₀, u), nx₁ = lerp(n₀₁, n₁₁, u) 4) wynik = lerp(nx₀, nx₁, v)
Pass: Przykład
Pełny przykład liczbowy
Dane wejściowe
Komórka siatki: narożniki (0,0), (1,0), (0,1), (1,1). Punkt zapytania: P = (0,3; 0,6).
Sprawdzenie: w samym narożniku (np. P→(0,0)) wynik musi wyjść 0 — wektor odległości do tego narożnika ma długość zero, więc jego iloczyn skalarny zeruje się niezależnie od gradientu.
Worked.example.geometrysame numbers as above
Ten sam narożny układ co w tabeli obliczeń wyżej — sprawdź swój rysunek na kartce z tym.
Pass: Fade
Czemu fade, nie liniowa interpolacja
Gdybyś interpolował liniowo (u=Px, v=Py, bez funkcji fade), noise miałby nieciągłą pochodną na granicach komórek — widoczne jako subtelne „załamania” przy oświetlaniu powierzchni bump-mappingiem. Perlin użył w 1985 wielomianu 3t²−2t³ (klasyczny smoothstep). „Improved Perlin Noise” z 2002 zamienił go na kwintyczny 6t⁵−15t⁴+10t³ — ten ma zerową drugą pochodną na końcach, nie tylko pierwszą, co jeszcze bardziej wygładza przejścia widoczne w oświetleniu.
Fade.function.comparisonlinear vs cubic vs quintic
Wszystkie trzy zaczynają w 0 i kończą w 1 — różnią się tym, jak płasko podchodzą do końców.
Z praktyki
To dlaczego implementacja szumu Perlina w każdym silniku ma dokładnie te trzy elementy: tablicę losowych gradientów (albo permutacji, jak w oryginalnym kodzie Perlina), funkcję fade i interpolację. Jeśli piszesz własny node „Noise” w shaderze proceduralnym, te cztery kroki z tego rozdziału to cała logika — resztę (3D, więcej oktaw) dokładają kolejne części tego wykładu.
Słowniczek
Funkcja fade
Wielomian wygładzający współrzędną przed interpolacją, np. 6t⁵−15t⁴+10t³.
Interpolacja biliniowa
Ważone uśrednienie 4 wartości narożnych (Rozdział 9).
lerp(a,b,t)
a + t·(b−a) — interpolacja liniowa między a i b.
Co dalej
Część 3 pokazuje, jak z tej jednej funkcji zbudować złożone, wielowarstwowe wzory — oktawy i fractal Brownian motion, dokładnie to, co robił parametr numOctaves w feTurbulence z Rozdziału 9.