Jedna całka opisuje cały transport światła
Rasteryzacja – technika stojąca za grami w czasie rzeczywistym – szybko rysuje trójkąty i fałszuje oświetlenie przy użyciu wielu oddzielnych sztuczek: mapy cieni, osłona otoczenia, zbadane promienie świetlne, odbicia przestrzenne ekranu, każda rozwiązująca jeden wąski problem. Path tracing podejmuje zupełnie inny podbój: bezpośrednio analizuje fizyczną równanie, które rządzi ruchem światła przez scenę, po raz pierwszy sformalizowane przez Jamesa Kaji’ego w 1986 roku jako równanie renderowania.
L_o(x, ω_o) = L_e(x, ω_o) + ∫_Ω f_r(x, ω_i→ω_o) · L_i(x, ω_i) · (ω_i · n̂) dω_i L_e = emisja powierzchni f_r = BRDF (jak powierzchnia rozprasza światło) L_i(x, ω_i) = L_o(x', −ω_i) — rekurencyjne: światło padające wejściowe jest światłem wychodzącym w innym miejscu ω_i · n̂ = cos θ_i, współczynnik kosinusa Lambertowskiego; Ω = półkulę powyżej powierzchni Ponieważ L_i po prawej stronie zależy od L_o w jakimś innym punkcie, równanie jest rekurencyjne – rozwijane, stanowi ono nieskończoną sumę wszystkich ścieżek o dowolnej długości: światło bezpośrednie, jeden odbit, dwa odbicia i tak dalej. Każdego efektu wizualnego, który renderer mógłby chcieć – miękkie cienie, wyciek kolorów, kwasowość – już zawiera się w tej jednej całce. Całe wyzwanie path tracingu polega na jej efektywnej oszacowaniu.
L_o(x, ω_o) = L_e(x, ω_o) + ∫_Ω f_r(x, ω_i→ω_o) · L_i(x, ω_i) · (ω_i · n̂) dω_i L_e = the surface's own emission f_r = the BRDF (how the surface scatters light) L_i(x, ω_i) = L_o(x', −ω_i) — recursive: incoming light IS outgoing light elsewhere ω_i · n̂ = cos θ_i, the Lambertian cosine term; Ω = the hemisphere above the surface
Szacowanie całki poprzez rzucanie kośćmi
Całka półkulowa nie ma zamkniętej postaci dla dowolnej sceny, więc jest przybliżana przez całkowanie Monte Carlo: narysuj N losowych kierunków, oceń funkcję wyznacznika w każdym z nich i uśrednij.
∫ f(x) dx ≈ (1/N) Σ f(xᵢ) / p(xᵢ) xᵢ wyciągnięte z gęstości prawdopodobieństwa p Obserwowane: E[szacowanie] = prawdziwa całka, dla dowolnego N Odchylenie standardowe ∝ 1/√N → 4x więcej próbek tylko połowę zmniejsza widoczny szum To zbieżność 1/√N jest definiującym ograniczeniem całej dziedziny: dlatego świeżo rozpoczęty renderowany ślad promieniowy wygląda na ziarnisty i powoli się wygładza, oraz dlaczego tak wiele wysiłku badawczego poświęca się albo redukcji wariancji na próbkę (ważne próbkowanie, następny zdarzenie), albo usuwaniu szumów z wyniku zamiast brutalnego zwiększania liczby próbek.
∫ f(x) dx ≈ (1/N) Σ f(xᵢ) / p(xᵢ) xᵢ drawn from probability density p Unbiased: E[estimate] = the true integral, for any N Standard deviation ∝ 1/√N → 4x more samples only halves the visible noise
BRDF: Jak powierzchnia faktycznie rozprasza światło
Termin BRDF – czyli funkcja rozpraszania rozproszonego (Bidirectional Reflectance Distribution Function) opisuje materiał. Idealnie matowa (Lawembertowska) powierzchnia ma najprostszą możliwą funkcję BRDF, f_r = albedo/π, co oznacza równomierne rozpraszanie światła padającego z każdej strony. Rzeczywiste materiały – np. metal wżynany, tworzywa sztuczne, skóra – zazwyczaj modelowane są przy użyciu funkcji BRDF mikrofacet, takiej jak GGX, która traktuje powierzchnię jako statystyczne pole małych luster i łączy funkcję rozpraszania oparte na normalnej dystrybucji, termin geometrycznego cienia maski oraz współczynnik odbicia Fresnela w jednym fizycznie uzasadnionym łobie odbiciową, która ciągle sięga od ostrych lusterek po miękkie, połyskujące refleksy.
Śledzenie jednej ścieżki z kamery
Rdzeń pętli wystrzeli promień z kamery, odbija go od tego, co uderza w niego, zgodnie z BRDF powierzchni, i gromadzi emitowane światło po drodze, ważone przez bieżącą współczynnik przepuszczalności, który śledzi, ile oryginalnego światła przeżywa każdy odbicie:
tracePath(promień, maxDepth = 8): przepustowość = 1; promieniowanie = 0 for głębokość w 0..maxDepth: uderzenie = scena.przecinaj(promień); jeśli !uderzenie: przerwać promieniowanie += przepustowość * uderzenie.materiał.emisja (wi, pdf, brdfVal) = uderzenie.materiał.próbuj(uderzenie.normalna, promień.kierunek) przepustowość *= brdfVal * cos(uderzenie.normalna, wi) / pdf // BRDF * kosinus / pdf promień = {pochodzenie: uderzenie.punkt, kierunek: wi} zwróć promieniowanie Wybór wi równomiernie w całym półkuli byłby marnowaniem większości próbek na kierunki, które niewiele wnoszą. Ważne próbkowanie zamiast tego rysuje wi z rozkładu ukształtowanego jak całka - dla powierzchni Lambertowskiego, ważone kosinusem próbkowanie półkulowe wybiera kierunki proporcjonalne do cos θ, co wygodnie wyzerowuje kosinusowy termin w aktualizacji przepustowości.
tracePath(ray, maxDepth = 8):
throughput = 1; radiance = 0
for depth in 0..maxDepth:
hit = scene.intersect(ray); if !hit: break
radiance += throughput * hit.material.emission
(wi, pdf, brdfVal) = hit.material.sample(hit.normal, ray.dir)
throughput *= brdfVal * cos(hit.normal, wi) / pdf // BRDF * cosine / pdf
ray = { origin: hit.point, dir: wi }
return radiance
Zatrzymanie bez uprzedzenia: rosyjska ruleta
Ograniczanie długości ścieżki promieniowania do stałej głębokości jest proste, ale wprowadza systematyczny błąd – długie ścieżki światła (np. przez szkło do jasnego źródła) są obcinane za każdym razem i ich wkład jest całkowicie tracony. Rosyjska ruleta losowo kończy ścieżkę zamiast tego, z prawdopodobieństwem przeżycia q – często luminansem aktualnej przepływowości – i skaluje wszystkie przetrwałe ścieżki przez 1/q. Ponieważ E[(przepływowość/q) * q] = przepływowość, oszacowanie pozostaje bezstronne, nawet jeśli większość indywidualnych ścieżek jest obcinana, co pozwala rendererowi ograniczyć najgorszy koszt bez systematycznego ciemnienia obrazu.
Frequently asked questions
Dlaczego śledzenie ścieżek generuje szumy w obrazach przy niskiej liczbie próbek?
Śledzenie ścieżek oszacowuje całkę równania renderingu za pomocą losowych próbek Monte Carlo, a odchylenie standardowe tego oszacowania spada proporcjonalnie do 1/√N. Podwojenie liczby próbek na piksel tylko dzieli szumy w połowę, dlatego obraz ostateczny zazwyczaj potrzebuje setek lub tysięcy próbek, chyba że stosowane są metody redukcji szumów lub inteligentne próbkowanie.
Co to jest rosyjska ruletka i dlaczego nie wpływa na wynik?
Rosyjska ruletka losowo kończy ścieżkę światła z prawdopodobieństwem 1−q, a skaluje wskaźnik przyczyniający się do przetrwania przez 1/q. Ponieważ wartość oczekiwana (wkład/q) × q równa się oryginalnemu wkładowi, oszacowanie pozostaje bezstronne średnio, nawet jeśli poszczególne ścieżki są przycinane — co pozwala rendererowi ograniczyć długość ścieżki bez systematycznego ciemnienia obrazu.
Dlaczego śledzenie ścieżek uzyskuje globalne oświetlenie i miękkie cienie za darmo?
Rasteryzacja przybliża oświetlenie oddzielnymi hackami — mapy cieni, osłona otoczenia, wypalane sondy oświetleniowe — dołączonymi indywidualnie. Śledzenie ścieżek zamiast tego bezpośrednio oblicza całkę renderingu, podążając za losowo próbkowanymi ścieżkami światła przez scenę, dzięki czemu pośrednie odbicia, wyciek kolorów i miękkie cienie obszarowe pojawiają się automatycznie z tej samej fizycznej całki, bez specjalnych przypadków kodu dla każdego efektu.
Wypróbuj na żywo
Wszystko powyżej działa bezpośrednio w Twojej przeglądarce — otwórz the simulation i zmieniaj parametry podczas działania. Nic nie jest instalowane ani przesyłane na serwer, cały model działa w jednej karcie.
▶ Otwórz symulację the simulation