GRAPH · scene treeXFORM · parent∘childINSTANCE · shared BVHRAY · to local space
Rozdział 17 / Zastosowania praktyczne

Struktury sceny, transformacje i instancing

Mamy już kompletny silnik światła. Zostało pytanie równie praktyczne: jak w ogóle zorganizować milion obiektów, kamerę i światła w jedną strukturę, którą ten silnik przetestuje.

TL;DR
Pass: Hierarchia

Scena jako drzewo transformacji

Koło samochodu nie ma sensownej „pozycji w świecie” zapisanej na trwałe — ma pozycję względem nadwozia, nadwozie względem węzła całego samochodu, a ten dopiero względem świata. Gdy samochód rusza, każde koło porusza się automatycznie, bo dziedziczy transformację rodzica, a ten swojego. To jest dosłownie ten sam mechanizm co parent/child w outlinerze Mayi albo Blendera.

M_world = M_parent · M_localmacierze transformacji składają się przez mnożenie, od korzenia drzewa aż do konkretnego obiektu
↓ Dodatek F — co dokładnie jest w środku macierzy M
Scene.graphparent → child
WORLD SAMOCHÓD (T1) NADWOZIE (T2) KOŁO_PL (T3) KOŁO_PP (T4)
Każde T to transformacja względna do rodzica. Koło nie wie, gdzie jest w świecie — zna tylko swoją pozycję względem nadwozia, nadwozie względem samochodu, a samochód względem świata. Poruszenie SAMOCHODU przesuwa cały łańcuch pod spodem.
Pass: Instancing

Jedna siatka, tysiące kopii

Las z dziesięciu tysięcy drzew nie potrzebuje dziesięciu tysięcy kopii geometrii i BVH w pamięci. Instancing przechowuje jedną „master” siatkę z jednym BVH, a każde wystąpienie w scenie to tylko odniesienie do niej plus własna macierz transformacji (pozycja, rotacja, skala).

↓ Dodatek I — dwa różne budżety kosztu geometrii
Instancing1 mesh, N transforms
MASTER MESH + BVH T_a T_b T_c T_d
Cztery instancje, jedna siatka w pamięci — każda różni się tylko macierzą transformacji.

Żeby to zadziałało bez kopiowania geometrii, promień testowany przeciw instancji jest transformowany odwrotną macierzą instancji do jej lokalnej przestrzeni — i tam trafia w dokładnie tę samą siatkę i BVH, co każda inna instancja.

ray_local = M⁻¹ · ray_world
hit_world = M · hit_localM — macierz transformacji instancji (z wyżej); promień idzie do przestrzeni lokalnej jej odwrotnością, a wynik trafienia wraca do świata tą samą macierzą wprost
Transform.the.raynot the geometry
ŚWIAT LOKALNIE (OBJECT SPACE) test jak w Rozdziale 4/13
Ten sam promień, ta sama siatka — tylko obrócona i przesunięta w jedną albo drugą stronę macierzą M.
Z praktyki

Instancje w Blenderze, Houdinim (copy-to-points) czy Unrealu (Instanced Static Mesh) to dosłownie ten mechanizm — dlatego rozsypanie dziesięciu tysięcy kopii tego samego kamienia kosztuje ułamek pamięci dziesięciu tysięcy unikalnych siatek.

W pipeline'ach opartych o USD — Solaris i Karma w Houdinim, Arnold czy RenderMan wpięte przez Hydrę — ten mechanizm ma dwie osobne nazwy, które warto rozróżniać. Native instancing to dokładnie powyższe: wiele prymitywów wskazujących na tę samą geometrię. PointInstancer idzie dalej i trzyma tysiące transformacji jako tablice punktów, bez tworzenia osobnego węzła na każdą kopię — dzięki temu las z miliona drzew nie rozdyma samego pliku sceny, nie tylko pamięci renderera.

Import z OBJ, FBX, glTF czy USD sprowadza się do wypełnienia dokładnie tych struktur: pozycje wierzchołków (Rozdział 2), normalne (Rozdział 4), UV (Rozdział 9) i hierarchia transformacji z tego rozdziału. Żaden z tych formatów nie wymaga nowej matematyki — tylko innego układu bajtów na dysku.

Słowniczek
Scene graph
Hierarchiczna struktura transformacji obiektów w scenie.
Transformacja lokalna / world
Pozycja względem rodzica kontra pozycja finalna w świecie.
Instancing
Wiele wystąpień jednej siatki, różniących się macierzą transformacji.
Object space
Lokalny układ współrzędnych siatki, niezależny od jej umiejscowienia w scenie.
Idź głębiej
Dodatek F — Macierze i współrzędne jednorodne Dodatek I — Złożoność geometrii a obciążenie Dodatek AH — Displacement i subdivision w czasie renderu