MIP · log2(footprint)FILTER · tri/aniso/EWADIFF · ray differentialsEXT OF · R.9
Dodatek G / Głębiej: Tekstury

Mipmapping i filtrowanie tekstur

Rozdział 9 nauczył Cię filtrowania biliniowego — dobrego, gdy zbliżasz się do tekstury. Ten dodatek pokazuje odwrotny problem: co się dzieje, gdy tekstura jest daleko albo widziana pod kątem, i czemu jeden teksel przestaje wystarczać.

TL;DR
Pass: Problem

Kiedy jeden teksel to za mało: minifikacja

Rozdział 9 zajmował się powiększeniem — jeden piksel ekranu mniejszy niż jeden teksel, więc interpolujesz między kilkoma. Minifikacja to sytuacja odwrotna: tekstura widziana z daleka albo pod kątem, gdzie jeden piksel ekranu odpowiada za dziesiątki teksli. Próbkowanie tylko jednego z nich (nawet biliniowo, czyli czterech) ignoruje resztę — dokładnie ten sam rodzaj aliasingu z Rozdziału 8, tylko na detalu tekstury, nie na krawędzi geometrii.

Pass: Mipmapy

Piramida wstępnie zmniejszonych wersji

Mipmapping wstępnie liczy ciąg coraz mniejszych, poprawnie uśrednionych (nie tylko przerzedzonych) wersji tekstury — każdy poziom w połowie rozdzielczości poprzedniego. Renderer szacuje, jak duży obszar tekstury pokrywa piksel (z pochodnych ekranowych współrzędnych UV — jak szybko UV zmienia się między sąsiednimi pikselami) i wybiera poziom, którego rozmiar teksla z grubsza odpowiada temu obszarowi.

poziom_mip ≈ log2( max(|∂uv/∂x|, |∂uv/∂y|) · rozmiar_tekstury )∂uv/∂x, ∂uv/∂y — jak szybko UV zmienia się wzdłuż pikseli ekranu; większa zmiana = wyższy (bardziej rozmyty) poziom mip
Mip.pyramideach level pre-averaged
mip 0 (pełna rozdz.) mip 1 mip 2 mip 3
Każdy poziom to prawdziwa, uśredniona wersja poprzedniego — nie zwykłe zmniejszenie obrazka.
Pass: Filtrowanie

Trójliniowe i anizotropowe

Filtrowanie trójliniowe próbkuje biliniowo (Rozdział 9) z dwóch sąsiednich poziomów mip naraz i miesza je liniowo — wygładza „przeskakiwanie” między poziomami przy ruchu kamery.

Mipmapping zakłada, że odcisk piksela na teksturze jest z grubsza kwadratowy. Pod płytkim kątem — klasyczna podłoga uciekająca w dal — odcisk jest długim, wąskim prostokątem: krótki w jedną stronę, bardzo długi w drugą. Zwykła mipmapa musi wybrać jeden poziom dla obu wymiarów naraz — albo rozmywa zbyt mocno w kierunku krótkim, albo zbyt mało w długim. Filtrowanie anizotropowe próbkuje kilka punktów wzdłuż wydłużonego kierunku, z wyższego (ostrzejszego) poziomu mip, i uśrednia — zachowując ostrość tam, gdzie się liczy.

Footprint.isotropic.vs.stretchedgrazing angle
ODCISK KWADRATOWY ODCISK ROZCIĄGNIĘTY (KĄT PŁYTKI) 1 próbka mip wystarczy kilka próbek wzdłuż rozciągnięcia
Ten sam ekranowy piksel — po prawej jego odcisk na teksturze jest dużo dłuższy niż szerszy.
Pass: Ray differentials

Skąd ray tracer w ogóle zna wielkość odcisku

Wzór na poziom mip z poprzedniej sekcji zakłada, że masz gotowe ∂uv/∂x i ∂uv/∂y — jak szybko UV zmienia się między sąsiednimi pikselami ekranu. W rasteryzacji to dosłownie gratis: GPU liczy piksele w kwadracikach 2×2 i sprzętowo porównuje UV sąsiadów. Ray tracer nie ma sąsiadów za darmo — każdy promień jest niezależny, a po odbiciu czy załamaniu może polecieć w zupełnie inną stronę niż promień z piksela obok.

Rozwiązanie (Igehy, 1999): ray differentials. Obok promienia głównego śledzisz dwa dodatkowe, „bliźniacze” promienie — jeden wystrzelony tak, jakby wyszedł z piksela o jeden w prawo, drugi jakby o jeden w górę. Wszystkie trzy zaczynają nieskończenie blisko siebie. Po każdym odbiciu czy załamaniu propagujesz różnicę między promieniem głównym a bliźniaczymi analitycznie — z lokalnej krzywizny powierzchni i kąta padania, bez faktycznego śledzenia trzech pełnych promieni (to byłoby 3× drożej). W punkcie trafienia porównujesz UV promienia głównego z UV, które dałyby promienie bliźniacze — ta różnica jest ∂uv/∂x i ∂uv/∂y.

∂uv/∂x ≈ uv(promień_x) − uv(promień_główny)promień_x — bliźniaczy promień odpowiadający przesunięciu o jeden piksel w osi x; analogicznie ∂uv/∂y z promienia_y
Ray.differentials3 rays, 1 hit test
POWIERZCHNIA / TEKSTURA kamera promień główny uv(główny) uv(promień_x) uv(promień_y)
Trzy promienie zaczynają nieskończenie blisko siebie — różnica ich UV w punkcie trafienia daje rozmiar odcisku.
Pass: EWA

EWA: produkcyjny standard

Zwykłe filtrowanie anizotropowe z poprzedniej sekcji zakłada, że odcisk piksela to prosty prostokąt wyrównany z osiami tekstury — w praktyce, gdy tekstura jest jeszcze do tego obrócona względem ekranu, odcisk jest elipsą pod dowolnym kątem, nie prostokątem. EWA (Elliptically Weighted Average, Greene i Heckbert, 1986) bierze tę elipsę wprost z ray differentials, próbkuje teksele wewnątrz niej z wagą gaussowską (środek elipsy waży najmocniej, brzegi najsłabiej) — i, żeby nie próbkować setek tekseli dla bardzo dużych, rozciągniętych odcisków, robi to na odpowiednio dobranym poziomie mipmapy, nie na pełnej rozdzielczości.

To dokładnie dlatego EWA (albo bardzo bliski wariant) jest domyślnym filtrem w RenderManie, Arnoldzie i PBRT: jedyny z opisanych tu filtrów, który poprawnie obsługuje odcisk dowolnie rozciągnięty i dowolnie obrócony naraz, nie tylko rozciągnięty wzdłuż osi UV.

Z praktyki

„Anisotropic Filtering: 2×/4×/8×/16×” to ustawienie karty graficznej i gry kontrolujące, ile próbek wzdłuż rozciągnięcia pozwala wziąć filtr. Mipmapy generują się automatycznie przy imporcie tekstury w Unity/Unrealu — ale bardzo drobne wzory (tekst, cienkie linie) potrafią migotać nawet z dobrym filtrowaniem, stąd wytyczne dla artystów tekstur o unikaniu ekstremalnie wysokich częstotliwości w powtarzalnych wzorach.

Koszt ray differentials i EWA to realne dodatkowe operacje na każdym promieniu — ale to inwestycja, która się zwraca: nieodfiltrowana, aliasująca tekstura wygląda jak szum, a szum kosztuje znacznie więcej próbek na piksel do wygładzenia (Rozdział 8, Rozdział 19), niż kosztowałoby jej poprawne odfiltrowanie za pierwszym razem. Płacisz trochę więcej na promień, żeby zapłacić dużo mniej próbek na piksel.

Słowniczek
Minifikacja
Sytuacja, gdy piksel ekranu pokrywa wiele teksli tekstury.
Mipmapa
Piramida wstępnie uśrednionych, coraz mniejszych wersji tekstury.
Poziom mip
Wybrany stopień piramidy, szacowany z pochodnych UV względem ekranu.
Filtrowanie trójliniowe
Interpolacja między dwoma sąsiednimi poziomami mip.
Filtrowanie anizotropowe
Wielopróbkowe filtrowanie wzdłuż rozciągniętego odcisku piksela.
Ray differentials
Dwa dodatkowe, nieskończenie bliskie promienie śledzone obok głównego, dające ∂uv/∂x i ∂uv/∂y.
EWA (Elliptically Weighted Average)
Filtrowanie eliptyczne z wagą gaussowską — obsługuje odcisk rozciągnięty i obrócony naraz.