Dodatek A pokazał clearcoat jako dwa niezależne loby, dodane do siebie. To działa wizualnie zaskakująco dobrze — ale ignoruje coś realnego: światło, które wpada pod warstwę lakieru, odbija się od bazy, i zamiast wyjść od razu, odbija się jeszcze raz od spodu lakieru, wraca w dół, i próbuje jeszcze raz. Ten dodatek liczy, ile energii to naprawdę znaczy.
Lakier na drewnie, pot na skórze, powłoka ochronna na metalu, warstwa wosku na owocu — w każdym z tych przypadków masz fizycznie dwa (albo więcej) niezależnych ośrodków, każdy ze swoim IOR i roughness, ułożonych jeden na drugim. Światło, zanim dotrze do „prawdziwego" materiału pod spodem, musi najpierw przejść przez warstwę wierzchnią — a to, co odbije się od bazy, musi przejść przez nią jeszcze raz, w drugą stronę, żeby w ogóle do Ciebie dotrzeć.
Model z Dodatku A liczy dwa niezależne loby: jeden Fresnel-ważony odbity wprost od górnej warstwy (clearcoat), drugi — zwykła BRDF bazy, przyciemniona o to, ile światła w ogóle przeszło przez górną warstwę. To dobre przybliżenie, bo ignoruje wszystko, co dzieje się światłu, które przeszło w dół, odbiło się od bazy, i próbuje wrócić w górę: zakłada, że po prostu wychodzi, za pierwszym podejściem, bez strat.
Uprośćmy do skrajności: udawajmy, że górna warstwa ma jedną liczbę opisującą, ile światła odbija z powrotem w dół, patrząc od spodu (R_góra), a baza ma jedną liczbę opisującą, ile ze światła, które do niej dotrze, odbija z powrotem w górę (R_baza). Każdy „obieg” (w dół, odbicie od bazy, próba ucieczki w górę, odbicie od spodu górnej warstwy z powrotem w dół) mnoży pozostałą energię przez r = R_góra · R_baza. To dokładnie ta sama struktura co Σ ze strony Podstawy matematyczne — tylko licząca nieskończenie wiele coraz słabszych powtórzeń tego samego zdarzenia:
To dlatego prosty model z Dodatku A wygląda dobrze na wprost, ale bywa zauważalnie za ciemny na krawędziach zaokrąglonych, lakierowanych obiektów (błotnik samochodu, polerowana podłoga) — dokładnie tam, gdzie kąt patrzenia zbliża się do stycznego.
Wzór z poprzedniej sekcji działa tylko dlatego, że skurczyliśmy każdą warstwę do jednej liczby. Prawdziwa BRDF bazy i prawdziwy Fresnel górnej warstwy zależą od kąta — nie ma jednego r, tylko r(θ), inny dla każdego kierunku. Zamkniętego wzoru na sumę takiej serii zwykle nie da się już wyprowadzić. Produkcyjne renderery (Arnold, RenderMan) rozwiązują to losowym spacerem (random walk): promień wchodzący w stos warstw jest symulowany krok po kroku — na każdej granicy między warstwami losujesz, zgodnie z lokalnym Fresnelem, czy się odbija, czy przechodzi — dokładnie tak jak w path tracingu z Rozdziału 15, tylko warstwy stosu pełnią rolę „sceny", a przejścia między nimi rolę odbić. Promień kończy wędrówkę, gdy ucieknie z powrotem w stronę kamery, ucieknie w głąb bazy (zaabsorbowany), albo ruletka rosyjska z Rozdziału 15 go zatrzyma.
To podejście automatycznie liczy dokładnie tę samą serię geometryczną co wyżej — tylko metodą Monte Carlo, próbka po próbce, zamiast jednym zamkniętym wzorem — i działa dla dowolnej liczby warstw, dowolnych BRDF na każdej granicy, bez żadnych uproszczeń skalarnych.
Każda dodatkowa warstwa to potencjalnie więcej odbić/załamań do prześledzenia na jedno trafienie — dla stosu N warstw, w najgorszym razie promień może odbijać się między nimi wielokrotnie, zanim ucieknie. W praktyce ten sam mechanizm ruletki rosyjskiej z Rozdziału 15, który ogranicza głębokość rekurencji w zwykłym path tracingu, ogranicza też długość spaceru między warstwami — bez niego koszt teoretycznie nie miałby górnej granicy.
„Coat Weight” i „Coat IOR” w Standard Surface (Arnoldzie) czy „Clearcoat” w Principled BSDF to interfejs do dokładnie tego, co opisuje ten dodatek — artysta ustawia grubość/IOR/roughness każdej warstwy, a stochastyczne warstwowanie w tle liczy resztę. Widoczny efekt „ciemnych krawędzi” na źle ustawionym coat to najczęściej znak, że silnik nie liczy energii uwięzionej między warstwami (starszy, uproszczony model) — warto to sprawdzić w dokumentacji, zanim zaczniesz kompensować to ręcznie podbitą jasnością bazy.
Dodatek AD zamyka wątek BRDF pytaniem praktycznym: skoro znasz już kształt loba GGX, jak losować kierunki próbek tak, żeby trafiać tam, gdzie lob faktycznie ma wartość, zamiast marnować próbki na kierunki niemal zerowe.