SAMPLES/PX · NPATTERN · JITTEREDAA · ONNOISE · stochastic
Rozdział 8 / Realizm i jakość obrazu

Antyaliasing i próbkowanie

Mamy kompletny model materiału z Rozdziałów 5–7. Ale jeden promień na piksel z Rozdziału 3 wciąż daje poszczekane krawędzie. Czas to naprawić — nie zmieniając ani jednego wzoru na kolor, tylko to, ile razy go liczymy.

TL;DR
Pass: Problem

Dlaczego linie są poszczekane

W Rozdziale 3 każdy piksel dostał jeden promień, wystrzelony przez jego środek. To traktuje piksel jako punkt — a piksel to w rzeczywistości mały kwadrat obrazu. Gdy krawędź obiektu przechodzi przez ten kwadrat, próbka ze środka daje odpowiedź binarną: promień trafił albo nie trafił, bez żadnego stanu pomiędzy.

Wzdłuż ukośnej krawędzi ta binarność układa się w charakterystyczne „schodki” — aliasing. To nie błąd w Twoim kodzie przecięć z Rozdziału 4; to fundamentalne ograniczenie próbkowania sceny w jednym punkcie na piksel.

Aliasing.staircase1 vs N spp
s = 1 → N = 1 (1 próbka/piksel)
TA SAMA KRAWĘDŹ, ROSNĄCA LICZBA PRÓBEK
Przesuń s — każda komórka to prawdziwy ułamek pokrycia z s×s podpróbek; przy s=1 dostajesz dokładnie binarną decyzję jednego promienia przez środek piksela.
Pass: Supersampling

Więcej niż jeden promień na piksel

Prosta naprawa: zamiast jednej próbki w środku piksela, weź N próbek rozłożonych po jego obszarze, wystrzel promień z każdej, uśrednij wyniki.

color_pixel = (1/N) · Σ trace(ray_i), i = 1…NN promieni na piksel, każdy z innej pozycji podpikselowej; wynik to prosta średnia

Najprostszy rozkład to regularna siatka — podziel piksel na N×N komórek i strzelaj przez środek każdej. To już naprawia krawędzie z poprzedniego diagramu. Ale regularna siatka ma swój własny problem: jeśli scena zawiera regularny wzór — cienkie linie płotu, siatkę okienną, teksturę w kratkę — regularne próbkowanie może z nim „rezonować”, produkując pulsujący wzór zwany moiré. Naprawiasz jeden rodzaj aliasingu i przypadkiem tworzysz inny.

Pass: Jitter

Losowość jako lekarstwo

Rozwiązanie: zamiast strzelać dokładnie przez środek każdej komórki siatki, dodaj do pozycji małe, losowe przesunięcie — wciąż jedna próbka na komórkę (więc rozkład jest wciąż równomierny, tzw. stratified sampling), ale już nie w idealnie regularnej pozycji.

próbka(i,j) = ( (i+ξ)/N , (j+ξ)/N )i, j — indeks komórki w siatce N×N wewnątrz piksela; ξ — niezależna losowa liczba z [0,1) dla każdej współrzędnej
Sampling.patternregular vs jittered
SIATKA REGULARNA STRATIFIED + JITTER
Ta sama liczba próbek, ten sam podział na komórki — jitter tylko rozbija regularność, która powoduje moiré.

Ludzkie oko jest dużo bardziej tolerancyjne dla przypadkowego szumu niż dla regularnego wzoru — dlatego zamiana strukturalnego aliasingu na losowy szum jest realną poprawą, nawet gdy liczba próbek się nie zmienia.

Pass: Ile i jak zsumować

Adaptacja i filtr rekonstrukcji

Wzór z tego rozdziału mówi „weź N próbek i uśrednij”. Produkcyjny renderer robi dwie rzeczy inaczej — i obie siedzą w suwakach, które kręcisz najczęściej.

Po pierwsze: N nie jest stałe. Gładkie niebo jest gotowe po czterech próbkach; krawędź gałęzi na tle tego nieba potrzebuje stu. Adaptive sampling wystrzeliwuje najpierw garść próbek, mierzy, jak bardzo się między sobą różnią, i dosypuje kolejne tylko tam, gdzie rozrzut przekracza próg. Ustawiasz więc nie jedną liczbę, a trzy: minimum próbek, maksimum próbek i próg, poniżej którego piksel uznajemy za gotowy.

To dlatego podniesienie „max samples” z 256 na 512 często prawie nie zmienia czasu renderu — jeśli próg jest osiągany wcześniej, ten limit nigdy się nie aktywuje. I odwrotnie: obniżenie progu potrafi wydłużyć render kilkukrotnie przy nietkniętym maksimum.

Po drugie: to nie jest zwykła średnia. Próbki nie należą wyłącznie do „swojego” piksela — renderer waży je funkcją rozciągającą się poza jego granice. Ta funkcja to filtr rekonstrukcji:

color_pixel = Σ w(Δx_i, Δy_i) · trace(ray_i)  /  Σ w(Δx_i, Δy_i)Δx_i, Δy_i — przesunięcie próbki i względem środka piksela; w — waga z filtra, malejąca wraz z odległością. Wzór z początku rozdziału to szczególny przypadek: filtr „box” o szerokości 1 piksela, gdzie w = 1 wewnątrz piksela i 0 poza nim, więc suma wag redukuje się do N
Reconstruction.filterbox / gaussian / mitchell
ZASIĘG FILTRA piksel liczony · zasięg wag KSZTAŁT WAGI w(Δ) 0 1 −1 px środek +1 px box — ostry, aliasuje gaussian — miękki mitchell — ostrzejszy, ale schodzi poniżej zera w < 0
Filtr sięga poza liczony piksel — próbka z sąsiada też wnosi wkład, tylko z mniejszą wagą. Ujemne „listki” Mitchella wyostrzają obraz, ale potrafią wygenerować ciemną obwódkę przy bardzo jasnej krawędzi (ringing), a w skrajnym przypadku ujemną wartość piksela.

Szerokość filtra to osobny suwak od liczby próbek i miesza się z nią w diagnozie: obraz „miękki mimo wysokich sampli” to najczęściej za szeroki filtr, nie za mało próbek. Zwiększanie N takiego obrazu nie wyostrzy — usunie tylko szum.

Z praktyki

Slider „Samples” albo „AA Samples” w Arnoldzie, V-Rayu, Cyclesie czy Unrealu to dosłownie N z tego rozdziału. Więcej próbek = gładsze krawędzie i mniej szumu z innych stochastycznych efektów (miękkie cienie z Rozdziału 6, GI w dalszych rozdziałach) — ale czas renderu rośnie liniowo z N.

Produkcyjne renderery rzadko używają czystego losowego jittera — z prostego powodu: czysta losowość potrafi przypadkiem skupić kilka próbek blisko siebie w jednym rogu piksela, a zostawić pustkę w drugim. Przy małym N widać to jako nierówny, „grudkowaty” szum, mimo że każda próbka jest tak samo losowa jak każda inna.

Sekwencje o niskiej dyskrepancji (najpopularniejsza w produkcji: Sobol) rozwiązują to inaczej niż stratified sampling z tego rozdziału — zamiast dzielić piksel na sztywne komórki, generują punkty tak, żeby każdy fragment przestrzeni próbek dostał sprawiedliwy udział, bez luk i bez skupisk, dla dowolnego N, nie tylko dla N będącego kwadratem liczby całkowitej (jak siatka komórek). W praktyce zbiegają się do poprawnego wyniku szybciej niż czysto losowe próbkowanie — mniej próbek daje ten sam poziom szumu.

Blue noise gra w zupełnie inną grę: nie chodzi o szybszą matematyczną zbieżność, tylko o to, gdzie ląduje błąd w domenie częstotliwości. Oko jest dużo bardziej tolerancyjne na szum wysokoczęstotliwościowy (drobne, przypadkowe ziarno) niż na szum niskoczęstotliwościowy (większe, widoczne plamy) — ten sam mechanizm percepcyjny, na którym opiera się dithering w kompresji obrazu. Wzorce blue noise są skonstruowane tak, żeby przy tej samej liczbie próbek przesunąć błąd w stronę wysokich częstotliwości — wynik wygląda czyściej, nawet gdy wariancja jest identyczna jak przy losowym próbkowaniu.

Z perspektywy artysty żadna z tych technik nie wymaga implementacji — to zwykle jedna pozycja w rozwijanym menu „Sampler” (Sobol, Correlated Multi-Jittered, Progressive…), obok samego slidera „Samples”. Zasada z tego rozdziału zostaje ta sama: wiele próbek, uśrednionych, byle nie w regularnym wzorze — różnica jest tylko w tym, jak sprytnie te próbki są rozłożone.

Adaptacja i filtr nazywają się w każdym silniku inaczej, ale sterują dokładnie tym, co opisuje sekcja wyżej. W Arnoldzie: AA Samples plus Adaptive Sampling z AA Samples Max i Adaptive Threshold, a filtr to Filter Type (domyślnie gaussian o szerokości 2,0). W RenderManie próg nazywa się Pixel Variance, a domyślnym filtrem jest blackman-harris. W Karmie (Houdini/Solaris) to Min/Max Pixel Samples plus Noise Level. W Cyclesie — Max Samples i Noise Threshold.

Praktyczny wniosek z tych dwóch mechanizmów razem: gdy render jest wolny, sprawdź najpierw próg, nie maksimum próbek — to on decyduje, ile z tego maksimum faktycznie zostanie zużyte. A gdy obraz jest miękki mimo wysokich sampli, sprawdź szerokość filtra, bo liczba próbek nie ma z tym nic wspólnego.

Słowniczek
Aliasing
Postrzępione krawędzie wynikające z próbkowania sceny w jednym punkcie na piksel.
Supersampling
Uśrednianie wielu promieni na piksel z różnych pozycji podpikselowych.
Próbka (sample)
Jeden promień wystrzelony z konkretnej pozycji w obrębie piksela.
Stratified sampling
Podział piksela na komórki z jedną próbką w każdej — gwarantuje równomierne pokrycie.
Jittering
Losowe przesunięcie próbki wewnątrz jej komórki.
Moiré
Pulsujący wzór powstały z rezonansu regularnego próbkowania z regularną strukturą sceny.
Adaptive sampling
Dosypywanie próbek tylko tam, gdzie rozrzut między nimi przekracza próg; sterowane trójką min / max / próg.
Filtr rekonstrukcji
Funkcja wagi, z jaką próbka wnosi wkład do piksela; sięga poza jego granice. Box, gaussian, blackman-harris, mitchell.
Ringing
Ciemna obwódka przy jasnej krawędzi, skutek ujemnych listków filtra (np. mitchell).
Idź głębiej
Dodatek AK — Cryptomatte