SUBDIV · 4ⁿDICE · do mikropoligonówBOUNDS · AABB musi objąćEXT OF · R.9, R.17
Dodatek AH / Lookdev w praktyce

Displacement i subdivision w czasie renderu

Plik sceny waży dwieście megabajtów, a render zjada trzydzieści gigabajtów pamięci. Różnicę robi geometria, której w pliku nie ma — powstaje dopiero w rendererze, tuż przed pierwszym promieniem. Ten dodatek pokazuje, skąd się bierze i dlaczego jedno źle ustawione pole potrafi albo obciąć model, albo spowolnić render kilkukrotnie.

TL;DR
Pass: Subdivision

Cztery razy więcej, na każdą iterację

Modelarz oddaje siatkę bazową — kilka tysięcy czworokątów opisujących kształt, ale nie detal. Renderer, zanim cokolwiek policzy, dzieli każdy czworokąt na cztery mniejsze i wygładza pozycje wierzchołków (najczęściej schematem Catmulla-Clarka). Powtórzone n razy daje:

liczba czworokątów = N_bazowa · 4ⁿN_bazowa — liczba czworokątów w siatce oddanej przez modelarza; n — liczba iteracji podziału. Wzrost jest wykładniczy, więc różnica między n=3 a n=5 to nie „trochę więcej detalu”, tylko szesnastokrotnie większa siatka
Subdiv.growth4ⁿ na iteracje
n=0 · 1 n=1 · 4 n=2 · 16 n=3 · 64 jeden czworokąt bazowy, cztery iteracje
Cztery kroki na jednym czworokącie. Przy siatce bazowej liczącej 20 000 czworokątów n=4 daje ponad pięć milionów — i tyle właśnie trafia do BVH z Rozdziału 13.

Podział adaptacyjny. Stała liczba iteracji marnuje pamięć na obiekty daleko od kamery: postać w tle dostaje ten sam detal co ta na pierwszym planie. Dlatego renderery liczą podział adaptacyjnie, w przestrzeni ekranu — dzielą dopóty, dopóki krawędź czworokąta nie zejdzie poniżej zadanej długości w pikselach. Obiekt oddalający się od kamery automatycznie dostaje mniej geometrii, bez ingerencji artysty.

To ma konsekwencję, która bywa zaskoczeniem: zużycie pamięci zależy od kadru. Ta sama scena renderowana z bliska i z daleka to dwa różne budżety. Ujęcie, które „nagle” przestało się mieścić w pamięci, często nie zmieniło się w żaden inny sposób niż zbliżeniem kamery.

Pass: Displacement

Prawdziwa sylwetka, nie udawana

Mając gęstą siatkę, renderer przesuwa każdy jej wierzchołek — najczęściej wzdłuż normalnej, o wartość odczytaną z tekstury (Rozdział 9). Wynik różni się od normal mapy w trzech miejscach, których nie da się podrobić: sylwetka na krawędzi obiektu jest faktycznie poszarpana, cień własny pada z prawdziwych wypukłości, a przecięcia z inną geometrią zachodzą tam, gdzie naprawdę.

Wariant wektorowy (vector displacement) przesuwa wierzchołek w dowolnym kierunku, nie tylko wzdłuż normalnej — dopiero to pozwala wyrzeźbić nawisy i zawinięcia, których displacement skalarny z definicji nie potrafi.

P' = P + N · (tex(u,v) − zero) · heightP — pozycja wierzchołka po podziale; tex(u,v) — wartość z mapy displacement w tym punkcie UV; zero — wartość uznawana za „brak przesunięcia” (zwykle 0 albo 0,5 dla map ze środkiem w szarości); height — mnożnik w jednostkach sceny

Zwróć uwagę na zero. Mapa zapisana ze środkiem w 0,5 i wczytana z zerem ustawionym na 0 przesunie całą powierzchnię na zewnątrz, zamiast rzeźbić w obie strony — model spuchnie równomiernie. To jeden z częstszych objawów „displacement nie działa tak, jak w programie do rzeźbienia”.

Pass: Bounds

Pole, które trzeba wypełnić ręcznie

Tu pojawia się problem, który wynika wprost z Rozdziału 13. BVH buduje pudełka wokół geometrii, żeby móc odrzucać promienie bez testowania trójkątów. Ale przesunięcie jest znane dopiero po odczytaniu tekstury dla każdego wierzchołka — a renderer musi znać rozmiar pudełka wcześniej, żeby w ogóle zdecydować, które fragmenty siatki wygenerować.

Rozwiązanie jest niewygodne, ale jedyne: podajesz z góry, o ile maksymalnie geometria może się przesunąć. Renderer powiększa pudełka o tę wartość i dopiero potem liczy.

Displacement.boundsza malo / dobrze / za duzo
ZA MAŁO · obcięcie szczyt poza pudełkiem DOBRZE · ciasno wszystko objęte, bez luzu ZA DUŻO · pusty luz promienie wchodzą bez potrzeby
Pudełko za małe obcina to, co z niego wystaje — geometria po prostu znika. Za duże jest poprawne wizualnie, ale każdy promień przechodzący przez pustą górę pudełka wymusza test, który do niczego nie prowadzi. To dokładnie ten koszt, który SAH z Dodatku C stara się minimalizować.

Objaw zbyt małych granic jest charakterystyczny i łatwy do rozpoznania: geometria wygląda, jakby ktoś ściął jej wierzchołki płaszczyzną — bo dokładnie to się stało. Objaw zbyt dużych jest podstępniejszy, bo obraz jest poprawny; widać tylko czas renderu, który nie ma uzasadnienia w tym, co na obrazku.

Z praktyki

W Arnoldzie to grupa na siatce: subdiv_type (catclark albo linear), subdiv_iterations, subdiv_adaptive_metric i subdiv_pixel_error dla podziału adaptacyjnego, oraz disp_height, disp_zero_value i disp_padding — to ostatnie jest właśnie polem granic z sekcji wyżej. RenderMan dziedziczy tu wprost po REYES-ie i mówi o dicingu do mikropoligonów; Karma wystawia analogiczne kontrolki na prymie USD.

Kolejność diagnozy przy renderze, który nie mieści się w pamięci: najpierw sprawdź iteracje podziału na najcięższych obiektach, potem czy podział jest adaptacyjny, a dopiero na końcu tekstury. Zejście z n=5 na n=4 na jednym obiekcie tła potrafi zwolnić więcej pamięci niż cała reszta optymalizacji razem.

Osobna pułapka: displacement psuje instancing z Rozdziału 17 wtedy, gdy każda instancja dostaje inną mapę — wspólna siatka przestaje być wspólna i oszczędność pamięci znika. Instancje z tą samą mapą displacement zachowują się normalnie.

Słowniczek
Subdivision surface
Siatka bazowa plus reguła podziału (najczęściej Catmull-Clark); render generuje gęstą wersję sam.
Iteracja podziału
Jeden krok dzielenia; liczba czworokątów rośnie jak 4ⁿ.
Podział adaptacyjny
Zagęszczanie sterowane długością krawędzi w pikselach — zależne od kadru.
Dicing / mikropoligon
Podział do fragmentów rzędu piksela; termin z REYES-a, żywy w RenderManie.
Displacement bounds (padding)
Deklarowane maksymalne przesunięcie; powiększa pudełka BVH budowane przed odczytem tekstury.
Vector displacement
Przesunięcie w dowolnym kierunku, nie tylko wzdłuż normalnej; pozwala na nawisy.
Idź głębiej
Dodatek I — Złożoność geometrii a obciążenie Dodatek C — Budowa BVH: SAH