Nanite: Virtualizace geometrie | UE 5,5.1



Author:

Categories: PN3+DC3

Tagged with: | | | | | | | | | | |


Semi-deep dive do virtualizace geometrie v programu na tvorbu videoher UnrealEngine 5.0-5.1

Ve hrách a obecně tvorbě 3D scén byl vždy problém s poměrem množství geometrie a zobrazovaného detailu. I s nejnovějším hardwarem nedokážeme zobrazovat neomezené množství geometrie a tím pádem jí nahrazujeme. Jedná se například o textury jako jsou normal/ bump mapy, které vytváří dojem detailu. Otázkou je, jestli a jak je možné zobrazit tolik detailu a geometrie tak, abychom tyto textury nepotřebovali, jelikož tyto textury zabírají obrovské množství prostoru na disku, následně ve VRam grafické karty. Přestože technologie jako Virtual Texturing pomáhá a byl to obrovský zlom, tak se zvyšujícím se rozlišením obrazovek, zvětšováním světů a množství assetů tohle přestává být udržitelné. A tak se hledají způsoby, jakým je možné toto ovlivnit, změnit – např. používáním scalovaním detailu v zavilosti na blízkosti objektu a množství pixelů, které zabírají na obrazovce. Tento příspěvek trochu rozvíjí systém nanite pro Unreal Engine 5, který tento problém řeší.

(Pokud si chcete ušetřit čtení, podívat se na to do většího detailu, máte 2h volného času a umíte anglicky, tak můžete přejít na https://www.youtube.com/watch?v=TMorJX3Nj6U&ab_channel=UnrealEngine – Inside Unreal od tvůrců UE)

Možnosti scalingu detailu meshů a typu geometrií

1. Voxely

Výhody:

Nevýhody

2.Subdivision/ Multi-ress

Výhody:

  • nekonečná jemnost

Nevýhody

  • base cage má často mnohem více polygonů než herní assety
  • náročné na rendering, switching a drawcally

3. 2D a Vector Dispacement

Výhody:

Nevýhody

4. Point based rendering

Výhody:

Nevýhody

Trojúhelníky jako základ 3D grafiky (pro dobrý důvod)

Postup a rendering na GPU + nanite

Klasické LOD

Ve hrách je používají systémy LOD (level of detail), které se přepínají v závislosti na blízkosti ke kameře v několika úrovních. Obrovskou nevýhodou LOD-based assetů je nutnost vytvořit několik těchto úrovní detailu pro každý asset, k tomu odpovídající UV apod. Je to obrovský konzument času a herní studia stojí vysoké množství financí – platy 3D grafiků.

LOD 1, 2 a 3

LOD trojúhelníkové klasty nanite meshe

Pro (zatím) statické meshe nanite vytvoří při importování assetu systém několika LOD klastů – spojení trojúhelníků ve funkční celky – které se zobrazují v závislosti na tom, kolik místa zabírají na obrazovce aka kolik pixelů zobrazuje klastr. První taková myšlenka vznikla už před rokem 2000, ale nikdy se neimplementovala.

Ořezávání neviditelných klastrů

Pokud zaměříme naši optimalizaci množství geometrie a detailu na reálné množství pixelů, které zabírají na obrazovce, poté je jasné, že nepotřebujeme kreslit trojúhelníky, které nevidíme.

K tomu se využívá frustrum (boundary) culling a dvojí occlusion culling

Na prvním snímku kreslím všechnu geometrii co vidím. Pokud se pohnu do snímku 2 o pár cm/ metrů, využiji Hierarchy Z-Buffer (HZB) z minulého snímku, vyvolám nový HZB a porovnám, co je nové a co už je nakreslené. To mi dovolí kreslit jen ty klastry, co jsou nové a ušetřit tak výkon.

Visibility buffer

Když máme HZB, tak se můžeme posunout dále. Potřebujeme rasterizovat geometrii a textury/ materiály (do texturování a materiálů zde nebudeme zabíhat, to je téma samo pro sebe).

Máme hloubku a teď zapíšeme InstanceID a TriangleID

Klastrová hierarchie

Ve chvíli kdy máme HZB, máme materiály a máme geodata, tak přichází na řadu LOD. A Jak už bylo řečeno, není potřeba kreslit “neomezený počet trojúhleníků”, pokud máme omezený počet pixelů (při 4K zobrazení to je 8 294 400 pixelů, což v dnešní době není pro grafické karty problém vykreslit).

Důležité tedy je, že tento přístup volá po konzistentním množství trojúhelníků, posléze klastrů. Z toho nám vyplývá, že LOD by mělo být závislé na pohledu a ne vzdálenosti od kamery, jako tomu je u klasických herních assetů.

Trhliny mezi klastry

Pokud máme nezávislé LOD-klastry, tak se při prohazování LOD mohou vytvořit trhliny (jeden klastr se změní a druhý ne a kvůli redukci trojúhelníků vznikne díra – Co s tím?

Takto by to vypadalo, kdyby byly uzamčené hranice – velmi rychle se dojde k tomu, že už se nedá zjednodušovat
Pokud se odemknou hranice a klastry se spojují, je zjednodušování téměř neomezené

Spojování klastrů

Jak se tedy rozhodnu, jaké klastry spojit?

Možností je více. Ideální je spojit ty, které mají nejvíce společných hranic (edges), abychom omezili možnost vzniku trhlin. Existují pro to také METIS libraries – knihovny používané k optimalizaci těchto úkonů – je zde spousta složitých výpočtů a problémů, které je si potřeba hlídat – uzamčené hrany atd. (ostré překryvy (např. převisy střech) – spousta způsobů, jak optimalizovat – do toho zabíhat nebudeme.

Ideální situace ale vzniká tehdy, kdy je minimální počet povinných hranic mezi klastry, počet trojúhelníků v klastru je roven nebo co nejblíže číslu 128, ale nikdy více, aby se geometrie mohla rasterizovat. Je také dáno určité množství vertexů, přes které se klastr nesmí dostat kvůli material shaderům a v neposlední řadě je také dobré minimalizovat počet hranic (edgů) mezi klastry, aby bylo snazší je spojovat a systém běžel rychleji.

Systém spojování klastrů lze ilustrovat na obrázku nahoře. máme 4 sousedící klastry a ty spojíme do jednoho, vydělíme počet trojúhelníků na polovinu a rozdělíme tento klastry na 2. Hranice mezi těmito 2 klastry bude co nejdelší a bude tam co nejméně edgů.

Jaký LOD klastr použít?

Využití klastrů a jejich detailu závisí na více faktorech

Jak dosáhnou “nepostřehnutelnosti” přechodu LOD

Jak je možné, že si lokální změny geometrie nevšimnu?

Trojúhelníky/ klastry, které kreslíme (DrawCall) jsou velké maximálně jako 1 pixel – přechod tedy zajištuje jednoduše Temporal anti-aliasing (TAA)

TAA může vykazovat rovněž nějaké artefakty a chyby, jako třeba ghosting, ale systémy se zlepšují, takže TAA standard není

Rasterizace

Systém převedení vektorového prostředí do 2D obrazu HW vs. SW rasterizace.

Zahrnuto do Drawcallu pokud

SW rasterizace pro malé trojúhelníky/ klastry. Je efektivnější pro drobné trojúhelníky velikosti pixelů apod. Dříve se myslelo, že to je pomalejší než HW rasterizace, ale posun v technologiích to již překonal a pro menší trojúhelníky je dnes 3x rychlejší než HW rasterizace.

HW rasterizace pro velké trojúhelníky/ klasty – zjednodušeně – prování grafická karta.

SW rasterizace
HW rasterizace

Overdraw

Pokud používáme HZB z minulého snímku a vyvoláváme druhý na vykreslení toho, co je nové – GBuffer call, tak zákonitě vznikne overdraw v místech, kde je vysoké množství překrývajících se assetů/ klastrů. Další problém je, že pokud se facy meshů překrývají o méně než velikost klastrů, tak se vykreslují oba v GBufferu.

Ideální je se překrývání vyhnout co nejvíce – určitě to nejde úplně, ale hodně overdraws může způsobit snížení frameratu.

Vykresluji červený klastr, žlutý i modrý, i když z červeného vidím jen polovinu a část žlutého taky není vidět. Čím jsou větší trojúhelníky, tím budou větší klastry – lower-poly meshe nakonec mohou být náročnější pro nanite!

Malé instance

Na jeden klastr připadá cca 128 trojúhelníků a jedná se nejmenší jednotku. Co tedy dělat, když se mesh zmenší na 1 klastr a nemůže jít na menší množství?

To zatím nemá řešení, ale nabízí se možnosti spojování (merging), hierarchální instancování (instance instancí) apod.

Materiály, UV, IDs etc.

Materiály a shadow mapy jsou další částí nanite systému, který by si vyžádal nejen další příspěvek, ale samostatný vysvětlování s hlubším porozuměním systému nanite a streamingu dat. Pokud je to pro vás zajímavé, doporučuji:

Doporučuji: https://www.youtube.com/watch?v=TMorJX3Nj6U&ab_channel=UnrealEngine – Inside Unreal od tvůrců UE

A k čemu vám to je?

Zdroje a inspirace pro další bádání

https://www.nvidia.com/content/dam/en-zz/Solutions/events/siggraph2018/pdf/tuesday/sig1824-adam-marrs-rahul-sathe-adaptive-temporal-antialiasing.pdf
https://www.youtube.com/watch?v=3J3gq9BJbKE&ab_channel=GreenleafVision
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
https://news.itmo.ru/en/startups_and_business/innovations/news/9473/
https://www.unrealengine.com/en-US/blog/understanding-nanite—unreal-engine-5-s-new-virtualized-geometry-system
https://www.youtube.com/watch?v=P65cADzsP8Q&ab_channel=WilliamFaucher
https://docs.unrealengine.com/5.0/en-US/nanite-virtualized-geometry-in-unreal-engine/
https://www.elopezr.com/a-macro-view-of-nanite/
https://docs.unrealengine.com/5.0/en-US/virtual-shadow-maps-in-unreal-engine/
https://cdn2.unrealengine.com/nanite-for-educators-and-students-2-b01ced77f058.pdf
https://www.youtube.com/watch?v=NRnj_lnpORU&t=5489s&ab_channel=High-PerformanceGraphics
https://www.youtube.com/watch?v=eviSykqSUUw&t=1523s&ab_channel=SIGGRAPHAdvancesinReal-TimeRendering
https://www.youtube.com/watch?v=TMorJX3Nj6U&ab_channel=UnrealEngine
https://www.youtube.com/watch?v=Dc1PPYl2uxA&ab_channel=UnrealEngine
https://www.youtube.com/watch?v=xUUSsXswyZM&ab_channel=UnrealEngine
Blender
Unreal Engine 5.0
Unreal Engine 5.1