W Rozdziale 1 poznałeś intuicję. Teraz przechodzimy do liczb: jak zapisać promień jako wzór matematyczny i jak sprawdzić, czy trafia w sferę — pierwszy kształt, który zaprogramujesz.
TL;DR
Punkt (position) i wektor (direction) to różne rzeczy, mimo że oba to trójka liczb (x, y, z).
Promień to prosty wzór: P(t) = O + t·D — punkt startowy plus kierunek przeskalowany o parametr t.
Sprawdzenie, czy promień trafia w sferę, sprowadza się do równania kwadratowego ze szkoły średniej — tylko podstawionego pod inne litery.
Pass: Reprezentacja
Punkt czy wektor?
W większości silników i DCC-ek position i direction wyglądają identycznie — trójka (x, y, z). Matematycznie zachowują się jednak inaczej, i ta różnica będzie miała znaczenie już za chwilę.
Punkt — opisuje miejsce w przestrzeni: pozycję kamery, środek sfery, punkt trafienia.
Wektor — opisuje przesunięcie albo kierunek: kierunek promienia, normalną powierzchni, kierunek światła.
Kluczowa różnica: gdy przesuwasz (translate) scenę, punkty się przesuwają, a wektory kierunkowe — nie. Kierunek „w prawo” pozostaje „w prawo”, niezależnie od tego, gdzie stoisz. To dlatego w reprezentacji jednorodnej punkty i wektory bywa się oznacza inną „czwartą współrzędną” — ale na razie wystarczy sama intuicja.
Pass: Toolkit
Operacje, które będziesz używać bez przerwy
Cały ray tracing stoi na czterech operacjach na wektorach. Żadna z nich nie jest skomplikowana — chodzi tylko o to, żeby ich geometryczny sens wszedł w krew, bo pojawiają się dosłownie w każdym wzorze w tej książce.
Odejmowanie punktów → wektor. A − B to wektor prowadzący z punktu B do punktu A.
Długość (norma). |V| = √(x² + y² + z²) — jak daleko sięga wektor.
Normalizacja. u = V / |V| — ten sam kierunek, długość równa 1 (tzw. wektor jednostkowy, albo wersor). Prawie każdy wzór w ray tracingu zakłada, że kierunki są znormalizowane.
Iloczyn skalarny (dot product). A·B = Ax·Bx + Ay·By + Az·Bz = |A||B|·cosθ. To najważniejsza operacja w tej książce — mówi „jak bardzo zgodne kierunkowo są dwa wektory”. Używamy jej już za chwilę, do rozwiązania równania sfery, a w Rozdziale 5 do liczenia oświetlenia Lamberta.
Vector.toolkitOps · 3
Trzy operacje, które wracają w każdym kolejnym rozdziale tej książki.
Pass: Definicja promienia
Promień jako wzór
Mając wektory, możemy zapisać promień. Promień to punkt startowy O (origin — najczęściej pozycja kamery albo poprzedni punkt trafienia) i znormalizowany kierunek D. Każdy punkt na promieniu opisuje jeden wzór:
P(t) = O + t · Dt — skalar: „jak daleko wzdłuż D od punktu O”
t = 0 to sam punkt O. t = 1 to punkt w odległości |D| (czyli 1, jeśli D jest znormalizowany). Każde kolejne t oddala nas dalej w tym samym kierunku. W ray tracingu liczą się tylko t > 0 — promień „istnieje” fizycznie tylko przed kamerą, nie za nią.
Ray.parametrizeP(t) = O + t·D
t = 2,00 · P(t) leży 2,00 wzdłuż D od O
Przesuń t — punkt jedzie wzdłuż promienia; dla t<0 szarzeje, bo taki punkt fizycznie nie istnieje.
Pass: Ray–sphere intersection
Pierwsze przecięcie: promień i sfera
Sfera jest najprostszym kształtem do przecięcia, dlatego prawie każda książka o ray tracingu — ta też — zaczyna właśnie od niej. Sferę o środku C i radiusie r definiuje jeden warunek: każdy punkt P na jej powierzchni spełnia
|P − C|² = r²
Podstawiamy nasz wzór promienia w miejsce P i wprowadzamy pomocniczy wektor L = O − C (od środka sfery do kamery). Po rozwinięciu dostajemy klasyczne równanie kwadratowe:
a·t² + b·t + c = 0a = D·D (= 1, gdy D jest znormalizowany) · b = 2·(D·L) · c = L·L − r²
To dosłownie wzór ze szkoły średniej — litery a, b, c mają teraz geometryczne znaczenie. Rozwiązujemy go przez wyróżnik:
Δ = b² − 4ac
Δ < 0 → promień mija sferę, brak przecięcia.
Δ = 0 → promień jest tangentny, dotyka sfery w jednym punkcie.
Δ > 0 → dwa przecięcia: t₀ (bliższe) i t₁ (dalsze). Bierzemy najmniejsze dodatnie t jako pierwszy widoczny punkt trafienia.
Discriminant.casesΔ = 4(r²−d²)
d = 1,00 · r = 2,00 · Δ = 12,00 · HIT · Δ>0
d — odległość promienia od środka sfery po prostopadłej. Δ zmienia znak dokładnie przy d = r — dokładnie ten sam wyróżnik co we wzorze wyżej, tylko przepisany geometrycznie.
Pass: Zapowiedź
Co z innymi kształtami?
Sfera jest wygodna, bo jej równanie jest proste — ale świat nie składa się z samych kul. W kolejnych rozdziałach sprawdzimy przecięcia z płaszczyznami i trójkątami (czyli z każdą siatką, którą wyeksportujesz z Blendera albo Maya), korzystając z tych samych narzędzi: wektorów, iloczynu skalarnego i tego samego wzoru P(t) = O + t·D.
Słowniczek
Punkt
Pozycja w przestrzeni (kamera, środek sfery, punkt trafienia).
Wektor
Kierunek albo przesunięcie; niezmienny względem translacji.
Normalizacja / wersor
Skalowanie wektora do długości 1, zachowując kierunek.
Iloczyn skalarny (dot product)
Miara zgodności kierunkowej dwóch wektorów; dla wersorów równa cosθ.
Parametr t
Odległość wzdłuż promienia od punktu O w kierunku D.
Wyróżnik (discriminant, Δ)
Decyduje, czy promień mija, dotyka, czy przecina sferę w dwóch punktach.
Co dalej
W następnym rozdziale zajmiemy się tym, jak w ogóle wygenerować promień dla danego piksela obrazu — jak jego pozycja na ekranie zamienia się w konkretny wektor D, uwzględniając pole widzenia (FOV), proporcje obrazu i pozycję kamery. Dopiero potem wrócimy do kolejnych kształtów: płaszczyzn i trójkątów.