Poglavlje 30: Nanite -- Virtualna Geometrija
U ovom poglavlju ulazimo u jedan od najrevolucionarnijih sistema u istoriji renderovanja u realnom vremenu. Nanite je Epic-ov sistem virtualne geometrije koji je promenio pravila igre -- bukvalno. Razumecete kako Nanite omogucava renderovanje milijardi trouglova u realnom vremenu, zasto je to ranije bilo nemoguce, kako sistem interno funkcionise (klasteri, DAG hijerarhija, software i hardware rasterizer), sta Nanite moze a sta ne moze, i kako da ga koristite u svojim projektima sa punim razumevanjem njegovih mogucnosti i ogranicenja.
Uvod: Obecanje "beskonacne geometrije"
Zamislite ovaj scenario: imate 3D skeniran kip sa 33 miliona trouglova. Zelite da ga stavite u igru. Ne jedan -- zelite 500 kopija tog kipa, rasporedjenih po velikom otvorenom svetu. To je oko 16 milijardi trouglova samo za kipove.
Pre Nanite-a, ovo je bilo apsolutno nemoguce u real-time renderovanju. Morali biste da:
- Rucno napravite LOD-ove -- verzije kipa sa sve manje detalja (LOD0 sa 33M, LOD1 sa 500K, LOD2 sa 50K, LOD3 sa 5K trouglova). To je sati i sati rada za umetnika, za svaki mesh.
- Implementirate LOD tranzicije -- i gledate popping artefakte dok se mesh naglo menja iz jednog LOD-a u drugi.
- Rucno upravljate memorijom -- pazite koliko mesh-eva moze da stane u VRAM, pravite streaming sistem.
- Ogranicite gustinu scene -- ne mozete staviti previse objekata jer ce draw call-ovi, vertex processing i memory postati bottleneck.
Nanite je dosao i rekao: "Daj mi mesh sa 33 miliona trouglova. Ja cu se pobrinuti za sve ostalo."
I to radi. Zaista radi.
Nanite je sistem virtualne geometrije (virtualized geometry) koji automatski i u realnom vremenu odlucuje koliko detalja da prikaze za svaki deo svakog mesh-a u sceni, na osnovu toga koliko je vidljiv na ekranu. Nema rucnih LOD-ova. Nema popping-a. Nema limita na broj trouglova u izvornom mesh-u.
Ali Nanite nije magija -- iza njega stoji briljantna inzenjerija. Da biste ga pravilno koristili (i znali kada ga ne koristiti), morate razumeti kako radi ispod haube. Upravo to cemo uraditi u ovom poglavlju.
30.1 Sta je Nanite?
Definicija
Nanite je sistem virtualne geometrije (virtualized geometry system) koji renderuje masivne kolicine poligona u realnom vremenu, bez tradicionalnih LOD sistema, bez rucnog pojednostavljivanja mesh-eva, i sa prakticki beskonacnim budzetom za izvornu geometriju.
Rec "virtualna" ovde znaci istu stvar kao u "virtualna memorija" ili "virtualne teksture" -- sistem pravi apstrakciju koja omogucava rucavanje sa daleko vise podataka nego sto fizicki staje u memoriju u datom trenutku. Kao sto operativni sistem koristi stranicu (page) virtuelne memorije da bi programi "videli" vise RAM-a nego sto fizicki postoji, Nanite koristi klastere geometrije koji se dinamicki ucitavaju i oslobadjaju, tako da scena moze imati milijarde trouglova iako u VRAM-u u svakom trenutku stoji samo mali deo.
Zasto je Nanite revolucionaran?
Da biste shvatili znacaj Nanite-a, pogledajmo sta je bio status quo pre njega.
Tradicionalni rendering pipeline (detaljno obradjen u poglavlju 07) procesira geometriju ovako:
- CPU salje draw call za svaki mesh (ili grupu mesh-eva) na GPU
- Vertex shader procesira svaki vertex svakog poslatog mesh-a
- Rasterizer obradjuje svaki trougao
- Pixel shader se pokrece za svaki generisani fragment
Problem je ocugledan: ako mesh ima 33 miliona trouglova, GPU mora da procesira svih 33 miliona trouglova, cak i ako mesh zauzima 50 piksela na ekranu. Naravno, za to koristimo LOD sistem -- ali LOD zahteva rucni rad, ima diskretne skokove, i daleko je od idealnog.
Nanite menja paradigmu: umesto da salje cele mesh-eve na GPU, Nanite interno deli svaki mesh na hiljade sitnih klastera trouglova, organizuje ih u pametnu hijerarhiju, i za svaki frejm bira tacno pravu kolicinu detalja za svaki klaster, na osnovu toga koliko piksela taj klaster zauzima na ekranu.
Rezultat:
- Broj trouglova u izvornom mesh-u je nevazan -- mesh moze imati 100 trouglova ili 100 miliona, Nanite ce renderovati samo onoliko koliko je potrebno za trenutnu projekciju na ekran
- Nema vidljivih LOD tranzicija -- tranzicije se desavaju na nivou klastera (grupe od ~128 trouglova), sto je ispod praga percepcije
- Nema rucnog rada na LOD-ovima -- artist importuje high-poly mesh i gotovo
- Streaming je automatski -- samo potrebni klasteri su u memoriji
- Overdraw je minimizovan -- Nanite koristi visibility buffer koji garantuje da se materijal evaluira tacno jednom po pikselu
Istorijski kontekst
Nanite nije nastao iz nista. Ideje na kojima se zasniva imaju dugu istoriju:
- Clipmap (2004, Christopher Tanner et al.) -- hijerarhijski pristup terenu koji je inspirisao streaming aspekte
- Virtual Texturing (id Software, Megatexture, 2006) -- streaming tekstura po stranicama, analogan pristup za teksture
- Cluster-based rendering -- ideja o podeli mesh-a na klastere nije nova, ali Nanite-ova implementacija je daleko naprednija
- Software rasterization na GPU (NVIDIA, 2011) -- rani eksperimenti sa compute shader rasterizacijom
- UE5 Nanite (objavljen 2022 sa UE5.0) -- Epic-ov tim, predvodjen Brian Karis-om, spojio je sve ove ideje u koherentan, produkciono spreman sistem
Nanite je prvi put prikazan u cuvenom "Lumen in the Land of Nanite" tech demo-u u maju 2020, i odmah je izazvao ogromnu paznju. Demo je prikazivao scenu sa preko 16 milijardi trouglova koji se renderuju u realnom vremenu na PlayStation 5 -- nesto sto je do tada bilo nezamislivo.
30.2 Kako Nanite radi: Cluster-based rendering
Sada ulazimo u srce Nanite sistema. Ova sekcija je tehnicka, ali bez nje ne mozete zaista razumeti Nanite. Polako, korak po korak.
Podela mesh-a na klastere
Kada importujete mesh koji je Nanite-enabled u UE5, engine u pozadini obavlja znacajnu obradu. Prva stvar je podela mesh-a na klastere (clustering).
Klaster je grupa od priblizno 128 trouglova koji su prostorno bliski (geografski su susedni na povrsini mesh-a). Zasto bas 128? To je kompromis izmedju granularnosti (manji klasteri = preciznija LOD selekcija) i overhead-a (vise klastera = vise posla za CPU pri traversal-u).
Zamislite da imate kip lava sa 1 milion trouglova. Nanite ce ga podeliti na otprilike 7.800 klastera (1.000.000 / 128). Svaki klaster pokriva mali deo povrsine kipa -- mozda grivo, vrh njuske, komad sapice.
Originalni mesh (1M trouglova)
|
┌────────┬────────┼────────┬────────┐
| | | | |
Klaster 0 Klaster 1 ... Klaster 7800
(~128 tri) (~128 tri) (~128 tri)
Klasterizacija se radi tako da:
- Trouglovi unutar klastera budu prostorno koherentni (blizu jedni drugima na mesh-u)
- Granice izmedju klastera budu na mestima gde je geometrija relativno jednostavna (da bi se olaksalo spajanje pri LOD redukciji)
- Klasteri imaju otprilike isti broj trouglova (balansiranje)
Izgradnja LOD hijerarhije
Podela na klastere je samo prvi korak. Nanite zatim gradi hijerarhiju LOD nivoa od tih klastera.
Proces ide ovako:
- LOD 0 (najdetaljniji): originalni klasteri, svaki sa ~128 trouglova
- LOD 1: svaka grupa od otprilike 4 susedna klastera iz LOD 0 se spoji i pojednostavi. Cetiri klastera sa po 128 trouglova (ukupno ~512) se simplifikuju na ~128 trouglova i formiraju jedan klaster na LOD 1 nivou. Redukcija geometrije koristi mesh simplification algoritme (slicne onima u poglavlju 03).
- LOD 2: postupak se ponavlja -- grupe klastera iz LOD 1 se spajaju i simplifikuju
- Nastavlja se dok ne preostane mali broj klastera (ili jedan) koji predstavlja najjednostavniju verziju mesh-a
Kljucna stvar: na svakom LOD nivou, svaki klaster i dalje ima otprilike 128 trouglova. Ono sto se menja je koliki deo originalnog mesh-a taj klaster pokriva. Na LOD 0, jedan klaster pokriva mali delic mesh-a sa punom rezolucijom. Na LOD 5, jedan klaster moze da pokriva cetvrtinu ili pola mesh-a, ali sa drasticno smanjenom rezolucijom.
LOD 0: [C0] [C1] [C2] [C3] [C4] [C5] [C6] [C7] ... (7800 klastera)
\ / \ / \ / \ /
LOD 1: [C0'] [C1'] [C2'] [C3'] ... (~1950 klastera)
\ / \ /
LOD 2: [C0''] [C1''] ... (~490 klastera)
\ /
LOD 3: [C0'''] (~120 klastera)
\ /
LOD 4: [C0''''] (~30 klastera)
|
LOD 5: [Croot] (mali broj)
Svaki "red" u ovom dijagramu ima otprilike 4x manje klastera od prethodnog, ali svaki klaster i dalje ima priblizno isti broj trouglova (~128).
DAG -- Directed Acyclic Graph
Ova hijerarhija LOD nivoa se interno cuva kao DAG -- Directed Acyclic Graph (usmereni aciklicni graf).
Zasto DAG a ne obicno stablo (tree)? Zato sto jedan klaster nizeg LOD-a (detaljnijeg) moze da "pripada" kao dete vise klastera viseg LOD-a (grubljeg). Ovo se desava na granicama izmedju klastera: kad se cetiri klastera iz LOD 0 spoje u jedan klaster LOD 1, granicni trouglovi mogu biti deljeni. DAG struktura precizno predstavlja ove odnose.
Svaki cvor u DAG-u je klaster, i svaki cvor ima:
- Listu dece -- detaljniji klasteri koji ovaj klaster zamenjuje
- Listu roditelja -- grublji klasteri koji zamenjuju ovaj klaster
- Bounding sphere/box -- prostornu granicu klastera (za culling)
- Error metric -- mera greske simplifikacije u odnosu na originalni mesh
Zasto DAG, a ne obicni LOD?
Tradicionalni LOD sistem (poglavlje 03, sekcija o LOD) radi na nivou celog mesh-a:
Tradicionalni LOD:
Kamera blizu --> LOD 0 (ceo mesh, puna rezolucija)
Kamera srednje --> LOD 1 (ceo mesh, manje detalja)
Kamera daleko --> LOD 2 (ceo mesh, jos manje detalja)
Nanite DAG radi na nivou klastera:
Nanite:
Za klastere blizu kameri --> koristi LOD 0 klastere (pun detalj)
Za klastere srednje --> koristi LOD 1 klastere (srednji detalj)
Za klastere daleko --> koristi LOD 3 klastere (mali detalj)
... i sve ovo UNUTAR ISTOG MESH-a, u istom frejmu!
To znaci da jedan mesh moze imati prednji deo renderovan sa punom rezolucijom (jer je blizu kameri), a zadnji deo sa grubom rezolucijom (jer je daleko ili jedva vidljiv) -- sve bez ikakve vidljive tranzicije.
30.3 Runtime: Traversal i selekcija klastera
Sada dolazimo do najvaznijeg dela: sta se desava u realnom vremenu, za svaki frejm?
Screen-space error metric
Za svaki frejm, Nanite mora da odluci koji LOD nivo da koristi za svaki klaster u sceni. Ovo se radi na osnovu screen-space error metric-a.
Ideja je sledeca:
-
Svaki klaster (na svakom LOD nivou) ima prekalkulisanu object-space error -- meru koliko se razlikuje od originalne, najdetaljnije geometrije. LOD 0 klasteri imaju error 0 (jer su originalna geometrija). LOD 1 klasteri imaju malu error. LOD 5 klasteri imaju veliku error.
-
Za svaki frejm, ova object-space error se projektuje u screen space -- preracunava se u piksele na ekranu. Klaster koji je daleko od kamere ce imati malu screen-space error cak i ako je object-space error velika (jer je sve sitno na ekranu). Klaster blizu kamere ce imati veliku screen-space error cak i za mali object-space error.
-
Nanite bira najgrublji LOD nivo za svaki klaster cija je screen-space error ispod praga percepcije -- tipicno ispod 1 piksel.
Matematicki, za klaster sa object-space error e i bounding sphere koja se projektuje na ekran sa radijusom r piksela:
screen_error = e * (r / object_radius)
Gde je object_radius radijus bounding sphere u object space-u. Ako je screen_error < threshold (obicno ~1 piksel), taj LOD nivo je dovoljno dobar.
DAG traversal
Za svaki frejm, Nanite obavlja top-down traversal DAG-a:
- Pocni od korena (najgrublji LOD)
- Za svaki cvor (klaster), proveri: da li je screen-space error ovog klastera ispod praga?
- DA --> koristi ovaj klaster, ne idi dublje (dovoljno je detaljan za trenutni prikaz)
- NE --> zameni ovaj klaster njegovom decom (detaljnijim klasterima) i proveri svako dete
Ovaj process se brzo spusta do pravog LOD nivoa za svaki deo mesh-a. Rezultat je skup klastera -- nekima su LOD 0, nekima LOD 3, nekima LOD 5 -- koji optimalno pokrivaju ceo mesh sa tacno dovoljno detalja za trenutnu kameru.
[Root - LOD 5]
screen_error = 0.3px
DOVOLJNO DOBAR? DA za ovaj deo
[Child A - LOD 3] [Child B - LOD 3]
screen_error = 2.1px screen_error = 0.5px
NIJE DOVOLJNO! DOVOLJNO DOBAR!
[A1-LOD 1] [A2-LOD 1]
err=0.8px err=0.9px
DOBAR! DOBAR!
U ovom primeru, za jedan frejm, Nanite bi renderovao klastere A1 (LOD 1), A2 (LOD 1), i Child B (LOD 3) za razlicite delove istog mesh-a. Prednji deo (blizi kameri) koristi detaljnije klastere, zadnji deo koristi grublje.
Frustum i Occlusion Culling na nivou klastera
Pre nego sto uopste evaluira screen-space error, Nanite obavlja culling na nivou klastera:
Frustum culling: Ako je bounding sphere klastera potpuno van view frustum-a kamere, klaster se preskace. Ovo je isto kao standardni frustum culling (poglavlje 07), ali na mnogo finijoj granularnosti -- umesto celog mesh-a, culling se radi po klasteru.
Occlusion culling: Nanite koristi Hierarchical Z-Buffer (Hi-Z) iz prethodnog frejma da brzo odredi da li je klaster zaklonjen drugim geometrijom. Ako jeste -- preskace se. Ovo je kljucno za scene sa mnogo overlapping geometrije (gradovi, enterijeri).
Kombinacijom ovih culling tehnika, Nanite tipicno eliminise 90%+ klastera u sceni pre nego sto stignu do rasterizacije.
Seamless tranzicije -- bez popping-a
Jedno od najimpresivnijih svojstava Nanite-a je da nikada ne vidite LOD tranziciju. Tradicionalni LOD sistemi imaju vidljiv "pop" -- mesh se naglo promeni iz jednog LOD nivoa u drugi, i to se vidi. Neki sistemi koriste cross-fade (mešanje dva LOD-a), ali to je skupo jer zahteva renderovanje oba LOD-a istovremeno.
Nanite resava ovaj problem na elegantan nacin: tranzicije se desavaju na nivou klastera, a ne celog mesh-a.
Kada klaster treba da predje sa LOD 1 na LOD 0 (veci detalj), desava se sledece:
- Klaster LOD 1 se zamenjuje sa 4 klastera LOD 0
- Na granicama izmedju ovih klastera, geometrija je dizajnirana tako da se perfektno poklapa (matching edges) -- nema pukotina, nema naglih promena
- Prelaz se desava za grupu od ~128 trouglova, sto zauzima tako mali deo ekrana da ljudsko oko ne moze da primeti promenu
Ovo je jedan od kljucnih razloga zasto je Nanite-ova interna struktura toliko pazljivo dizajnirana -- klasteri moraju da se perfektno uklope na granicama izmedju razlicitih LOD nivoa. Ovo se obezbjedjuje tako sto se pri simplifikaciji granicni verteksi izmedju susednih klastera zakljucavaju (locked boundary) -- ne pomeraju se i ne uklanjaju tokom simplifikacije. Na taj nacin, dva susedna klastera razlicitog LOD nivoa uvek imaju identican red verteksa na zajednickoj granici.
30.4 Dva rasterizera: Software i Hardware
Ovo je jedan od najinovativnijih aspekata Nanite-a i zasluzuje pazljivu diskusiju.
Problem sa sitnim trouglovima
U poglavlju 09 (Rasterizacija) smo detaljno obradili kako GPU rasterizer radi. Podsetimo se kljucnog detalja: GPU procesira piksele u 2x2 quad-ovima. To znaci da cak i za trougao koji pokriva samo 1 piksel, GPU aktivira 4 piksela (3 su "helper lanes" -- izracunavaju se ali se rezultat ne koristi).
Za trouglove normalne velicine (pokrivaju desetine ili stotine piksela), ovaj overhead je zanemarljiv. Ali sta se desava kad mesh ima milione sitnih trouglova koji pokrivaju 1-2 piksela svaki?
Trougao od 1 piksela:
GPU procesira 4 piksela (1 koristan + 3 helper lane)
Efikasnost: 25%
Trougao od 100 piksela:
GPU procesira ~110 piksela (100 korisnih + ~10 helper lanes)
Efikasnost: ~91%
Za mesh sa milionima mikro-trouglova, efikasnost hardverskog rasterizera moze pasti na 10-25%, sto je katastrofalan gubitak. Osim toga, sam triangle setup (priprema edge equations, baricentricnih koeficijenata -- poglavlje 09, sekcija 1) ima fiksni cost po trouglu, koji dominira kad je trougao sitniji od piksela.
Ovo je fundamentalni problem za Nanite, jer Nanite-ovi klasteri na visim LOD nivoima cesto sadrze trouglove koji pokrivaju samo 1-2 piksela.
Software rasterizer
Nanite-ov odgovor na ovaj problem je custom software rasterizer -- implementiran kao compute shader na GPU-u.
Umesto da koristi hardverski rasterizer pipeline (vertex shader --> rasterizer --> pixel shader), Nanite pokrece compute shader koji:
- Ucitava trouglove iz klastera
- Za svaki trougao, izracunava koji pikseli su pokriveni (koristeci edge equations, isto kao hardverski rasterizer -- poglavlje 09)
- Direktno upisuje rezultat u visibility buffer (o kome cemo uskoro)
Zasto je ovo brze za sitne trouglove?
- Nema 2x2 quad overhead-a -- compute shader procesira individualne piksele, ne quad-ove
- Nema triangle setup overhead-a -- compute shader ima fleksibilniju kontrolu nad raspodjelom posla
- Nema ROP overhead-a -- nema blending hardware bottleneck-a, koristi se atomicni upis u buffer
- Bolji workload balancing -- compute shader moze da distribuira posao optimalno za sitne trouglove
Software rasterizer je optimizovan specijalno za slucaj gde su trouglovi manji od ili priblizno velicine piksela. Za vece trouglove, hardverski rasterizer je i dalje brzi jer je specijalizovani silicijum (fixed-function hardware) brzi od programabilnog compute shader-a za tipicne rasterizacione operacije.
Hardware rasterizer
Za klastere ciji trouglovi pokrivaju vise piksela (otprilike 32+ piksela po trouglu), Nanite koristi standardni hardverski GPU rasterizer. Ovo je isti pipeline koji smo detaljno obradili u poglavlju 07 i 09 -- vertex shader, triangle setup, scan conversion, fragment generation.
Nanite automatski odlucuje za svaki klaster da li da koristi software ili hardware rasterizer, na osnovu projicovane velicine trouglova klastera:
Za svaki klaster:
projicirana_velicina = prosecna povrsina trougla u screen pikszelima
if projicirana_velicina < ~32 piksela:
koristi SOFTWARE rasterizer (compute shader)
else:
koristi HARDWARE rasterizer (standardni GPU pipeline)
Pragovi se mogu razlikovati u zavisnosti od GPU arhitekture i verzije UE5, ali princip je isti.
Rezultat: dva puta, jedna slika
Na kraju, oba rasterizera (software i hardware) upisuju u isti visibility buffer. Iz perspektive ostatka pipeline-a, nema razlike -- rezultat je isti bez obzira koji rasterizer je koristio.
Scena sa Nanite mesh-evima
|
┌─────┴─────┐
| |
Klasteri Klasteri
(sitni (vecji
trouglovi) trouglovi)
| |
SOFTWARE HARDWARE
rasterizer rasterizer
| |
└─────┬─────┘
|
Visibility Buffer
Ovo je briljantno resenje jer kombinuje prednosti oba pristupa: efikasnost hardware rasterizera za normalne trouglove i efikasnost compute-based pristupa za mikro-trouglove.
30.5 Visibility Buffer
Visibility buffer je kljucna komponenta Nanite pipeline-a i zasluzuje sopstvenu sekciju.
Sta je visibility buffer?
U tradicionalnom renderovanju (forward ili deferred), rasterizacija i materijal evaluacija su spojeni -- dok rasterizer generise fragmente, pixel/fragment shader se odmah pokrece i evaluira materijal (teksture, normalne mape, PBR parametre itd.).
Nanite razdvaja ove dve faze:
-
Rasterization pass: generise samo visibility buffer -- za svaki piksel na ekranu cuva samo:
- Instance ID -- koji Nanite mesh instance je vidljiv na tom pikselu
- Cluster ID -- koji klaster tog mesh-a
- Triangle ID -- koji trougao unutar klastera
- Baricentricne koordinate -- pozicija piksela unutar trougla (za kasniju interpolaciju)
- Depth -- dubina piksela
-
Material evaluation pass: za svaki piksel, na osnovu podataka iz visibility buffer-a, ucitava odgovarajuce vertex atribute, interpolira ih, i evaluira materijal
Zasto ovaj pristup?
Visibility buffer pristup (koji smo pomenuli i u poglavlju 09 u sekciji o overdraw-u) ima nekoliko kljucnih prednosti:
1. Materijal se evaluira tacno jednom po pikselu
U tradicionalnom deferred renderingu, pixel shader se pokrece za svaki fragment koji stigne iz rasterizera -- ukljucujuci i fragmente koji ce biti prepisani (overdraw). Sa visibility buffer-om, materijal se evaluira samo za konacno vidljive piksele.
Tradicionalni:
Trougao A rastera → pixel shader za A → upisuje u GBuffer
Trougao B rastera (isti piksel) → pixel shader za B → prepisuje A u GBuffer-u
= 2x material evaluation, samo 1x koristan
Nanite Visibility Buffer:
Trougao A rastera → upisuje ID u visibility buffer
Trougao B rastera (isti piksel) → prepisuje ID u visibility buffer-u (jeftina operacija)
Material pass → evaluira materijal SAMO za B (konacno vidljiv)
= 1x material evaluation, 1x koristan
2. Kompatibilnost sa software rasterizer-om
Software rasterizer (compute shader) ne moze da pokrene standardni pixel shader -- on nema pristup hardverskom pipeline-u za fragment processing. Ali moze da upise ID i baricentricne koordinate u buffer. Visibility buffer je nacin da se premosti jaz izmedju software i hardware rasterizera.
3. Efikasnije dekodiranje atributa
Visibility buffer cuva minimalne podatke po pikselu (ID + baricentricne koordinate, tipicno 8 bajtova). GBuffer u deferred renderingu cuva mnogo vise (albedo, normal, roughness, metallic -- 16-32 bajta po pikselu). Za Nanite koji moze da ima ogroman overdraw na nivou rastera, manje podataka po pikselu znaci manje bandwidth-a.
Visibility Buffer i Virtual Shadow Maps
Visibility buffer nije vazan samo za Nanite -- on je i osnova za Virtual Shadow Maps (VSM) sistem koji cemo detaljno obraditi u poglavlju 31. VSM koristi Nanite-ov visibility buffer pristup za renderovanje senki sa enormnom rezolucijom, sto omogucava ostre, detaljne senke na svim razdaljinama.
30.6 Streaming geometrije
Jedna od najvaznijih ali cesto zanemarenih karakteristika Nanite-a je njegova sposobnost da dinamicki stream-uje geometriju sa diska.
Problem: VRAM je ogranicen
Moderna graficka kartica ima 8-24 GB VRAM-a. Zvuci kao mnogo, ali pogledajmo racunicu:
Jedan Nanite mesh sa 33 miliona trouglova (nakon Nanite obrade) zauzima otprilike 300-500 MB Nanite podataka (ukljucujuci sve LOD nivoe i klaster strukturu). Stavite 100 takvih mesh-eva u scenu i imate 30-50 GB Nanite geometrije. To ne staje u VRAM.
Ali ne morate da drzite sve u VRAM-u istovremeno. U svakom frejmu, kamera vidi samo deo scene, i za vecinu mesh-eva koristi grublje LOD nivoe. Stvarno potrebni podaci su samo mali procenat ukupnih.
Virtual Geometry Pages
Nanite organizuje svoje podatke u stranice (pages) -- slicno stranicama virtuelne memorije. Svaka stranica sadrzi podatke za grupu klastera.
Nanite mesh podaci na disku:
┌─────────┬─────────┬─────────┬─────────┬─────────┐
│ Page 0 │ Page 1 │ Page 2 │ Page 3 │ Page 4 │ ...
│LOD0 cl. │LOD0 cl. │LOD1 cl. │LOD2 cl. │LOD3 cl. │
└─────────┴─────────┴─────────┴─────────┴─────────┘
U VRAM-u u datom trenutku:
┌─────────┬─────────┬─────────┐
│ Page 2 │ Page 4 │ Page 7 │ (samo stranice koje su potrebne)
└─────────┴─────────┴─────────┘
Streaming sistem radi ovako:
- Request faza: Tokom DAG traversal-a, Nanite identifikuje koji klasteri su potrebni za trenutni frejm
- Prioritizacija: Klasteri se rangiraju po prioritetu -- koliko su vidljivi, koliko blizu kameri, da li su vec u VRAM-u
- Streaming: Stranice sa najvisim prioritetom se ucitavaju sa diska u VRAM, stranice sa najnizim prioritetom se evictuju (oslobadjaju)
- Fallback: Ako klaster jos nije ucitan, koristi se grublji LOD nivo (roditelj u DAG-u) koji je vec u memoriji
Streaming u praksi
Streaming je asinhroni -- ne blokira renderovanje. Ako se kamera naglo pomeri i mnogo novih klastera postane vidljivo, u prvim frejmovima ce se koristiti grublji LOD-ovi dok se detaljniji ucitavaju. Ovo je obicno neprimetno jer:
- Grublji LOD je vec u memoriji (uvek se cuva mali set grubih LOD-ova za svaki mesh)
- Streaming je brz (posebno sa NVMe SSD-ova)
- Tranzicija od grubog ka detaljnom LOD-u je seamless (nema popping-a)
U nekim ekstremnim slucajevima (veoma brz let kamere preko ogromne scene sa mnogo Nanite mesh-eva), mozete primetiti kratku fazu "pop-in" gde se geometrija progresivno ucitava. Ovo je kompromis koji Nanite pravi svesno -- bolje je prikazati grublju verziju odmah nego cekati.
Implikacije za storage
Nanite podaci su relativno veliki na disku. High-poly mesh od 33 miliona trouglova generise 300-500 MB Nanite podataka. Za velike projekte, ovo znaci da Nanite geometrija moze zauzeti desetine ili stotine gigabajta na disku.
Epic je optimizovao format za streaming, pa je vazno imati brz storage (SSD, idealno NVMe). Sa sporim HDD-om, streaming Nanite podataka moze da bude bottleneck i da prouzrokuje vidljive artefakte (grubi LOD-ovi koji predugo ostaju vidljivi).
30.7 Sta Nanite podrzava
Static Meshes (neprozirni)
Ovo je primarni use case za Nanite i funkcionise odlicno. Svaki Static Mesh u UE5 moze biti oznacen kao Nanite-enabled u Import Settings ili u mesh properties.
Tipicni kandidati za Nanite:
- Architektura: zgrade, zidovi, podovi, stepenice
- Prirodni elementi: stene, litice, tereni
- Propsovi: namestaj, vozila, masine, dekorativni elementi
- 3D skenovi: fotogrametrijske geometrije sa milionima trouglova
- CAD modeli: industrijski i arhitektonski modeli
Za sve ove slucajeve, Nanite dramaticno pojednostavljuje pipeline: importujete mesh sa punom rezolucijom, ukljucite Nanite, i gotovo. Nema potrebe za rucnim LOD-ovima, nema potrebe za retopologijom za renderovanje.
Masked materijali (sa ogranicenjima)
Od UE5, Nanite podrzava Masked blend mode materijale -- materijale koji koriste opacity mask za "izrezivanje" delova mesh-a (na primer, lisce na drvetu gde je sve osim lisca prozirno).
Medjutim, postoje ogranicenja:
- Performance cost: Masked materijali na Nanite mesh-evima su skuplji nego opaque, jer Nanite mora da evaluira opacity mask tokom rasterizacije da bi odredio vidljivost
- Pixel depth offset: ne radi sa Nanite masked materijalima
- Artefakti na ivicama: tamo gde mask tranzicija nije osetra (soft edges na maski), mogu se pojaviti artefakti jer Nanite radi na per-triangle nivou, ne per-pixel
Za mnoge slucajeve (vegetacija, ograde, resatoste strukture), masked Nanite materijali rade dovoljno dobro, ali za najkriticenije slucajeve testiranje je obavezno.
World Position Offset (WPO)
World Position Offset je materijalna funkcionalnost koja pomera vertekse mesh-a u vertex shader-u -- koristi se za animacije poput ljuljanja drveca na vetru, talasanje zastava, itd.
Nanite podrzava WPO, ali sa ogranicenjima:
- Performance cost: WPO na Nanite mesh-evima moze da disabluje neke Nanite optimizacije, jer se pozicija verteksa menja u runtime-u, sto komplikuje culling i LOD selekciju. Nanite mora da racuna sa bounding volume koji obuhvata sve moguce pozicije verteksa nakon WPO-a, sto moze znacajno povecati bounding box i smanjiti efikasnost culling-a.
- Evaluation per-vertex: WPO se evaluira per-vertex, sto znaci da za veoma grubu geometriju (visoki LOD nivoi), pomak moze da izgleda drugacije nego na detaljnoj geometriji
- Nanite mora biti upozoren: za mesh koji koristi WPO, morate oznaciti ovu opciju u Nanite settings da bi sistem pravilno azurirao bounding volume
Prakticni savet: WPO na Nanite mesh-evima je koristan za jednostavna pomeranja (ljuljanje drveca), ali za kompleksne vertex animacije, performanse mogu da trpe. Testirajte i profajlirajte.
Nanite Tessellation (UE 5.4+)
Pocevsi od UE 5.4, Epic je uveo Nanite Tessellation -- mogucnost da se Nanite mesh-evi tesselliraju u runtime-u za dodatni geometrijski detalj.
Ovo je fascinantno jer kombinuje prednosti oba sveta:
- Nanite obezbjedjuje baznu geometriju sa automatskim LOD-om
- Tessellation dodaje dodatne trouglove samo tamo gde je potrebno, bazirano na displacement map-i
Tessellation u kombinaciji sa Nanite-om se razlikuje od klasicne tessellation-a (poglavlje 07) na nekoliko nacina:
- Tessellation se primenjuje na Nanite klastere, ne na cele mesh-eve
- Nanite automatski upravlja LOD-om tesselliranih klastera
- Displacement mape se koriste za dodavanje visinskog detalja
Ovo omogucava, na primer, stenu sa relativno jednostavnom baznom geometrijom i detaljnom displacement mapom koja dodaje fine detalje povrsine. Nanite automatski tessellira samo klasteri koji su blizu kameri, dok udaljeni klasteri koriste grublju reprezentaciju.
Napomena: Nanite Tessellation je relativno nova funkcionalnost i moze imati ogranicenja i performance implikacije koje se menjaju sa svakom verzijom UE5. Uvek proveravajte dokumentaciju za vasu verziju.
Landscape (eksperimentalno)
Pocevsi od kasnijih verzija UE5 (5.4+), Epic je uveo eksperimentalnu podrsku za Nanite Landscape -- renderovanje terena kroz Nanite sistem umesto kroz tradicionalni landscape rendering.
Prednosti:
- Mogucnost koristenja visokodetaljne geometrije terena
- Automatski LOD kao za svaki Nanite mesh
- Bolja integracija sa ostatkom Nanite pipeline-a
Ogranicenja:
- Eksperimentalna funkcionalnost -- moze imati bagove i performance probleme
- Ne sve Landscape funkcionalnosti su kompatibilne (runtime virtual texturing interaction, neki painting slojevi)
- Tooling moze biti drugaciji od tradicionalnog Landscape workflow-a
Za produkcijske projekte, evaluirajte pazljivo da li je Nanite Landscape spreman za vase potrebe. Za prototipove i eksperimente, vredi isprobati.
30.8 Sta Nanite NE podrzava (ili ima ogranicenja)
Jednako vazno kao znati sta Nanite moze, je znati sta Nanite ne moze. Ova sekcija ce vas spreciti od frustracija i bagova u produkciji.
Translucent/Transparent materijali
Nanite ne podrzava transparentne materijale. Ovo je fundamentalno ogranicenje, ne implementacioni propust.
Zasto? Zato sto ceo Nanite pipeline zavisi od visibility buffer-a koji cuva samo jedan "pobednik" po pikselu -- trougao koji je najblizi kameri. Za neprozirne objekte, to je korektno -- vidite samo prednji trougao. Ali za transparentne objekte, morate da vidite i prednji transparentni objekat i ono sto je iza njega. Visibility buffer ne moze da sacuva ove informacije jer, po definiciji, cuva samo jednu instancu podataka po pikselu.
Dodatno, Nanite koristi depth-based culling agresivno -- objekti iza blizhih objekata se odbacuju. Za transparentne objekte, ovo bi znacilo da se pozadina iza stakla nikad ne renderuje.
Resenje: Za transparentne objekte (staklo, voda, efekti), koristite standardne (non-Nanite) mesh-eve sa tradicionalnim rendering pipeline-om. Ovi mesh-evi se renderuju u posebnom transparency pass-u, nakon sto je Nanite zavrsio sa neprozirnom geometrijom.
Skeletal Meshes (animirani likovi)
Skeletal meshes -- mesh-evi koji se deformisu animacijom -- imaju ogranicenu podrsku u Nanite i funkcionalnost se aktivno razvija.
Zasto je ovo tesko?
- Deformacija menja geometriju svakog frejma, sto znaci da se Nanite klasteri i njihove bounding sphere takodje moraju azurirati
- DAG hijerarhija je prekalkulisana za staticnu geometriju -- deformacija moze da poremeti odnose izmedju LOD nivoa
- Skinning (transformacija verteksa na osnovu kostiju) dodaje znacajan computational cost koji se multiplicira sa Nanite-ovim velikim brojem trouglova
Za likove u igri (koji su obicno 30.000-200.000 trouglova), Nanite uglavnom nije potreban -- tradicionalni LOD sistem sa 3-4 nivoa je sasvim dovoljan.
Medjutim, za filmske karaktare, virtualne produkcije, i druge use case-ove gde je potrebno renderovati likove sa milionima trouglova, Nanite za Skeletal Meshes bi bio izuzetno koristan. Epic aktivno radi na ovoj funkcionalnosti.
Vertex animacija -- ogranicenja
Vertex animacija (animacija koja pomera vertekse direktno, bez skeleta) ima ogranicenja slicna WPO-u:
- Moze se koristiti kroz WPO u materijalu
- Ali komplikuje bounding volume i culling
- Veoma kompleksne vertex animacije mogu da budu neefikasne sa Nanite-om
Vrlo tanka geometrija (single-sided lisca)
Mesh-evi sa veoma tankim elementima -- kao sto su listovi drveca, trava, ili drugi "papirasti" objekti -- mogu imati probleme sa Nanite-om:
Problem 1: LOD simplifikacija: Kada Nanite simplifikuje klastere za nize LOD nivoe, veoma tanki trouglovi mogu da se potpuno uklone ili da se spoje na neispravan nacin. List koji je jedan trougao debljine moze da "nestane" na LOD 2.
Problem 2: Software rasterizer i sub-pixel trouglovi: Veoma tanki trouglovi koji su gotovo linijskog oblika mogu da "nestanu" izmedju piksela -- rasterizer ih ne uhvati jer ne pokrivaju centar nijednog piksela.
Problem 3: Z-fighting: Dva bliska, paralelna trougla (prednja i zadnja strana lista) mogu da se bore za visibility na sub-pixel nivou, sto dovodi do treperenja (flickering).
Resenje: Za vegetaciju, cesto je bolje koristiti:
- Nanite sa masked materijalima za listove koji imaju dovoljnu debljinu
- Tradicionalne (non-Nanite) billboard ili card-based mesh-eve za travu i sitno lisce
- Kombinovani pristup: stablo koristi Nanite za stablo i deblje grane, a billboard-e za najsitnije lisice
Point i Line primitive
Nanite renderuje iskljucivo trouglove. Point primitive (tacke) i line primitive (linije) nisu podrzane. Ovo je retko ogranicenje u praksi, posto se vecina sadrzaja renderuje kao trouglovi, ali imajte na umu ako radite sa point cloud podacima ili wireframe vizualizacijama.
Rezime ogranicenja
| Funkcionalnost | Nanite podrska | Napomena |
|---|---|---|
| Opaque Static Mesh | Potpuna | Primarni use case |
| Masked materijali | Da, sa ogranicenjima | Performance cost, moguca artefakti |
| WPO (World Position Offset) | Da, sa ogranicenjima | Utice na culling efikasnost |
| Nanite Tessellation | Da (UE 5.4+) | Nova, proveravajte dokumentaciju |
| Landscape | Eksperimentalno | U razvoju, moze imati probleme |
| Translucent/Transparent | NE | Fundamentalno ogranicenje |
| Skeletal Meshes | Ograniceno, u razvoju | Funkcionalnost se aktivno prosledjuje |
| Point/Line primitive | NE | Samo trouglovi |
| Veoma tanka geometrija | Problematicno | Moguce artefakti, testirati |
30.9 Nanite Overdraw i Visibility
Cak i sa Nanite-om, overdraw postoji -- ali Nanite ga tretira drugacije od tradicionalnog renderinga.
Overdraw na nivou rastera
Tokom Nanite rasterizacije, vise trouglova moze da pokriva isti piksel. Ovo je normalno i neizbezhno -- isto kao u tradicionalnom renderovanju. Ali kljucna razlika je sta se desava sa overdraw-om:
Tradicionalno: Svaki put kad novi trougao pokrije vec popunjen piksel, pokrece se pixel shader za taj trougao. Ako imate 5 trouglova koji pokrivaju isti piksel, pixel shader se pokrece 5 puta (ili manje ako Early-Z elimninise neke).
Nanite: Svaki put kad novi trougao pokrije vec popunjen piksel, samo se azuriraju ID i depth u visibility buffer-u. Ovo je daleko jeftinija operacija -- nema material evaluation, nema teksture sampling, samo atomic compare-and-swap na integer buffer-u.
Materijal se evaluira tek u drugom prolazu, i to tacno jednom po pikselu, samo za konacno vidljive piksele.
Piksel (500, 300) -- tokom rasterizacije:
Trougao A (depth 0.5): Upisi ID=A, depth=0.5 u visibility buffer
Trougao B (depth 0.3): B je blizi! Upisi ID=B, depth=0.3 (prepisuje A)
Trougao C (depth 0.7): C je dalji od B, ne radi nista (atomic test fails)
Trougao D (depth 0.2): D je najblizi! Upisi ID=D, depth=0.2 (prepisuje B)
Materijal evaluacija: evaluiraj materijal SAMO za trougao D
Ukupno: 4 raster operacije (jeftine) + 1 material evaluation
Overdraw vizualizacija u UE5
UE5 ima vizualizacione modove koji vam omogucavaju da vidite Nanite overdraw:
-
Nanite Overview: Prikazuje opste informacije o Nanite renderovanju -- koji delovi scene koriste Nanite, koliko klastera je aktivno, itd.
-
Nanite Triangles: Vizualizuje gustinu trouglova -- boje od plave (malo trouglova) do crvene (mnogo trouglova) pokazuju koliko Nanite trouglova pokriva svaki piksel.
-
Nanite Overdraw: Prikazuje koliko puta je svaki piksel prepisan tokom Nanite rasterizacije. Plava = 1x (nema overdraw-a), zelena = 2-3x, crvena = 5x+.
Da pristupite ovim vizualizacijama u UE5 Editor-u:
Viewport > View Mode > Nanite Visualization > [izaberite vizualizaciju]
Ili preko konzolne komande:
r.Nanite.Visualize.Overview 1
r.Nanite.Visualize.Triangles 1
r.Nanite.Visualize.Overdraw 1
Minimizovanje Nanite overdraw-a
Iako je Nanite overdraw jeftiniji od tradicionalnog overdraw-a, nije besplatan. Preporuke:
- Koristite Hi-Z occlusion culling: Nanite ga koristi automatski, ali obratite paznju da objekti koji zaklanaju druge budu ranije u render order-u
- Izbegavajte nepotrebno overlapping geometriju: Mesh-evi koji se probijaju jedni kroz druge generisu overdraw
- Koristite distance culling: Za veoma udaljene objekte koji doprinose minimalno, razmotrite distance-based culling
- Profajlirajte: Nanite overdraw vizualizacija je vaš najbolji prijatelj za identifikaciju problema
30.10 Performance karakteristike
Ovo je mozda najvaznija prakticna sekcija ovog poglavlja. Razumevanje Nanite-ovih performance karakteristika je kljucno za pravilnu upotrebu.
"Trouglovi su besplatni" -- ta i ne bas
Nanite-ov marketinski slogan je da su trouglovi "besplatni". Ovo je priblizno tacno u ovom smislu: dodavanje vise trouglova izvornom mesh-u gotovo da ne utice na runtime performance.
Zasto? Zato sto Nanite ne renderuje sve trouglove. Bez obzira da li izvorni mesh ima 1 milion ili 100 miliona trouglova, Nanite ce u runtime-u renderovati otprilike isti broj trouglova -- onoliko koliko je potrebno da se popune pikseli na ekranu sa dovoljnom preciznoscu.
Zamislite mesh koji zauzima 10.000 piksela na ekranu. Nanite ce renderovati otprilike 10.000-30.000 trouglova za taj mesh (u zavisnosti od geometrije i LOD preciznosti), bez obzira da li izvorni mesh ima 50.000 ili 50.000.000 trouglova.
Ali "besplatno" nije doslovno tacno. Vise trouglova u izvornom mesh-u znaci:
- Vise Nanite podataka na disku i u memoriji (disk storage i VRAM za klaster hijerarhiju)
- Duze vreme importa i obrade (build time)
- Vise stranica za streaming -- moze da ugrozi streaming performance
Glavni troskovi u runtime-u
Nanite-ovi realni runtime troskovi su:
1. GPU: Rasterizacija vidljivih klastera
Ovo je primarni GPU trosak. Broj vidljivih klastera zavisi od:
- Rezolucije ekrana (vise piksela = vise klastera potrebno)
- Kompleksnosti scene (vise mesh-eva = vise klastera)
- Kolicine geometrije u view frustum-u
Na tipicnoj sceni, Nanite rasterizuje 50.000-500.000 klastera po frejmu. Ovo je efikasno zahvaljujuci software/hardware rasterizer hibridnom pristupu, ali i dalje ima realni GPU cost.
2. GPU: Material evaluation
Nakon sto visibility buffer odredi sta je vidljivo, materijal se evaluira za svaki vidljivi piksel. Ovo je isti cost kao u tradicionalnom deferred renderingu -- complexity materiala (broj tekstura, matematicke operacije u shader-u) direktno utice na performance.
Bitna razlika: Nanite garantuje da se materijal evaluira tacno jednom po pikselu. U tradicionalnom renderovanju, overdraw moze da prouzrokuje visestruku evaluaciju.
3. CPU: DAG traversal i cluster selection
Za svaki frejm, CPU mora da traversira DAG hijerarhiju za svaki Nanite mesh i odabere odgovarajuce klastere. Ovo je relativno jeftin proces jer:
- DAG je hijerarhijski, pa se ne moraju posetiti svi cvorovi
- Culling eliminise vecinu klastera rano
- Proces je paralelizovan
Ali sa veoma velikim brojem Nanite mesh instanci (desetine hiljada), CPU traversal moze da postane bottleneck. Profajlirajte sa stat Nanite konzolnom komandom.
4. CPU: Streaming management
Upravljanje streamingom geometrije -- odlucivanje koje stranice ucitati, koje osloboditi -- ima CPU cost koji raste sa brojem aktivnih Nanite mesh-eva i brzinom pomeranja kamere.
5. Memorija: VRAM za Nanite podatke
Nanite podaci u VRAM-u zauzimaju znacajnu kolicinu memorije. Na tipicnoj sceni, Nanite streaming pool moze da zauzme 256 MB - 1 GB VRAM-a. Ovo se konfigurira sa:
r.Nanite.StreamingPool.SizeInMB=512
Ako je pool premali, Nanite ce koristiti grublje LOD nivoe jer nema prostora da ucita detaljnije klastere. Ako je prevelik, ostaje manje VRAM-a za teksture i druge resurse.
Profajliranje Nanite-a
UE5 nudi nekoliko alata za profajliranje Nanite performance-a:
stat Nanite -- konzolna komanda koja prikazuje kljucne metrike:
- Broj vidljivih klastera
- Broj renderovanih trouglova
- Vreme rasterizacije (software i hardware, odvojeno)
- Streaming statistika
- Memory usage
GPU Profiler (Ctrl+Shift+,): Prikazuje detaljno vreme za svaku fazu Nanite pipeline-a:
NaniteRaster-- vreme rasterizacijeNaniteEmit-- priprema visibility buffer-aNaniteBasePass-- material evaluation
Nanite vizualizacioni modovi: Kao sto smo vec pomenuli (Overview, Triangles, Overdraw, itd.)
Prakticne preporuke za performance
-
Koristite Nanite za sve staticne opaque mesh-eve -- uglavnom nema razloga da ne koristite Nanite za staticne neprozirne objekte. Performance je tipicno jednaka ili bolja od tradicionalnog pristupa.
-
Obratite paznju na material complexity -- Nanite ne pomaze sa skupim materijalima. Ako imate materijal sa 20 teksturnih semplova i 500 instrukcija, Nanite nece magicno ubrzati material evaluation.
-
Konfigurisite streaming pool -- Premaleni streaming pool ce degradirati kvalitet geometrije. Preveliki ce uzimati VRAM od tekstura. Nadite balans za vas projekat.
-
Profajlirajte redovno -- Koristite
stat Nanitei GPU profiler da identifikujete bottleneck-ove. -
Pazite na instancing -- Nanite ne koristi GPU instancing na isti nacin kao tradicionalni rendering. Svaka Nanite mesh instanca ima svoj set klastera za selekciju. Hiljada instanci istog mesh-a nije "besplatna" u smislu CPU traversal-a.
-
Disk I/O -- Koristite SSD (NVMe je idealan) za brz streaming. HDD moze da bude ozbiljan bottleneck.
30.11 Nanite vs tradicionalni LOD
Ovo je pitanje koje se cesto postavlja: da li Nanite potpuno zamenjuje tradicionalne LOD-ove? Kratak odgovor: gotovo da, ali ne potpuno. Duzi odgovor zahteva razumevanje oba pristupa.
Tradicionalni LOD sistem
Tradicionalni LOD (Level of Detail) sistem, koji smo pomenuli u poglavlju 03, funkcionise ovako:
-
Artist pravi (ili automatski alat generise) vise verzija mesh-a sa razlicitim nivoima detalja:
- LOD 0: 100.000 trouglova (full detail)
- LOD 1: 25.000 trouglova
- LOD 2: 5.000 trouglova
- LOD 3: 1.000 trouglova
-
Engine bira koji LOD da prikaze na osnovu udaljenosti objekta od kamere (ili na osnovu screen size-a)
-
Tranzicija izmedju LOD-ova je diskretna -- mesh se naglo menja iz jednog LOD-a u drugi. Neki sistemi koriste cross-fade (dithering) da ublaže tranziciju.
Prednosti tradicionalnog LOD-a
- Potpuna kontrola umetnika: Artist moze da odluci tacno sta da ukloni na svakom LOD nivou, cuvajuci najvaznije detalje
- Predvidljiv performance: Svaki LOD ima tacno poznat triangle count
- Nema runtime overhead-a: Nema DAG traversal-a, nema streaming-a, nema cluster selection-a
- Radi sa svim tipovima mesh-eva: Static, Skeletal, sa svim materijalima
- Manji disk footprint: Nekoliko LOD-ova zauzimaju manje prostora od punog Nanite podatka
Prednosti Nanite-a
- Nema rucnog rada: Automatski LOD iz full-detail mesh-a
- Kontinualni LOD: Bezstepeni prelaz umesto diskretnih skokova
- Per-cluster granularnost: Razliciti delovi istog mesh-a na razlicitim LOD nivoima
- Bez popping-a: Tranzicije su neprimetne
- Neogranicen poly count: Izvorni mesh moze imati proizvoljan broj trouglova
- Automatic streaming: Geometrija se ucitava po potrebi
Kada Nanite zamenjuje tradicionalni LOD
Za staticne opaque mesh-eve u vecini slucajeva -- da. Ako mesh moze da koristi Nanite (statican, neproziran), gotovo uvek je bolje koristiti Nanite nego rucne LOD-ove. Nanite ce automatski generisati LOD hijerarhiju koja je bolja od onoga sto vecina artista moze da uradi rucno, i bez tranzicionih artefakata.
Kada tradicionalni LOD i dalje treba
-
Skeletal mesh-evi: Nanite jos uvek nema potpunu podrsku za skeletal mesh-eve. Za likove i animirane objekte, tradicionalni LOD je i dalje neophodan.
-
Transparentni objekti: Nanite ne podrzava transparentne materijale. Za staklo, vodu, efekte -- tradicionalni LOD.
-
Veoma mala geometrija u masi: Za travu, sitne kamencice, i druge objekte koji se koriste u ogromnim kolicinama i koji su vec low-poly, Nanite overhead (streaming, traversal) moze da bude veci od koristi. Tradicionalni LOD ili HISM (Hierarchical Instanced Static Mesh) moze da bude efikasnije resenje.
-
Platforme bez Nanite podrske: Ako ciljate platforme (stariji mobilni uredjaji, web) koji ne podrzavaju Nanite, morate imati fallback LOD-ove.
-
Precise kontrola nad LOD: U retkim slucajevima gde artist mora da ima potpunu kontrolu nad time sta se uklanja na svakom LOD nivou (na primer, karakter sa specificnim siluetama na svakom LOD-u), tradicionalni LOD nudi tu kontrolu.
Hibridni pristup
U praksi, vecina UE5 projekata koristi hibridni pristup:
- Nanite za staticne opaque mesh-eve: Arhitektura, stene, vecina propsova
- Tradicionalni LOD za skeletal mesh-eve: Likovi, neprijatelji, NPC-ijevi
- Tradicionalni LOD ili HISM za masovnu vegetaciju: Trava, sitno lisce
- Tradicionalni pristup za transparentne objekte: Staklo, voda, efekti
Scena u UE5:
┌──────────────────────────────────────────────────────┐
│ │
│ Nanite: Tradicionalni LOD: │
│ - Zgrade - Likovi (Skeletal) │
│ - Stene - Trava (HISM) │
│ - Teren (eksper.) - Staklo (Transparent) │
│ - Vehicli (staticki) - Efekti (Particles) │
│ - Dekoracija - Animirani propsovi │
│ │
└──────────────────────────────────────────────────────┘
30.12 Nanite u praksi: Workflow u UE5
Sada kad razumete teoriju, hajde da prodjemo kroz prakticni workflow koriscenja Nanite-a u UE5.
Aktiviranje Nanite-a pri importu
Kada importujete Static Mesh u UE5, u Import Settings cete videti opciju:
Build Nanite: [x] Enable
Checkmark-irajte ovu opciju i UE5 ce automatski generisati Nanite podatke za mesh. Ovo moze da potraje za veoma kompleksne mesh-eve (milioni trouglova) jer engine mora da izgradi klaster hijerarhiju i LOD piramidu.
Aktiviranje Nanite-a na postojecem mesh-u
Za mesh koji je vec importovan bez Nanite-a:
- Otvorite mesh u Static Mesh Editor-u
- U Details panelu nadjite Nanite Settings
- Postavite Enable Nanite Support na
true - Kliknite Apply Changes
Nanite Settings na mesh-u
Nanite Settings za mesh sadrze:
- Enable Nanite Support: On/Off
- Position Precision: Preciznost pozicije verteksa za Nanite reprezentaciju. Auto je obicno dovoljan.
- Percent Triangles: Kontrolise koliki procenat originalnih trouglova se cuva na najdetaljnijem LOD nivou. 100% cuva sve. Smanjivanje ove vrednosti moze da smanji velicinu Nanite podataka na racun kvaliteta.
- Trim Relative Error: Kontrolise koliko agresivno Nanite eliminise trouglove koji su ispod praga greske. Niza vrednost = vise trouglova sacuvano.
- Fallback Triangle Percent: Za non-Nanite fallback, koliki procenat originalnog mesh-a da sacuva.
Konzolne komande za Nanite
Evo korisnih konzolnih komandi za rad sa Nanite-om:
stat Nanite -- Prikazuje Nanite statistiku
r.Nanite.Visualize.Overview 1 -- Overview vizualizacija
r.Nanite.Visualize.Triangles 1 -- Triangle density vizualizacija
r.Nanite.Visualize.Overdraw 1 -- Overdraw vizualizacija
r.Nanite.StreamingPool.SizeInMB -- Velicina streaming pool-a
r.Nanite 0/1 -- Globalno ukljuci/iskljuci Nanite
r.Nanite.MaxPixelsPerEdge -- Kontrolise LOD preciznost
r.Nanite.Filter -- Filtriranje Nanite vizualizacije
Debugovanje Nanite problema
Problem: Mesh izgleda previse pojednostavljen
- Proverite
r.Nanite.MaxPixelsPerEdge-- mozda je previsok - Proverite streaming pool velicinu -- mozda je premali pa Nanite nema prostora za detaljne klastere
- Proverite
Percent TrianglesiTrim Relative Erroru mesh settings
Problem: Performance pad sa Nanite-om
- Koristite
stat Naniteda identifikujete bottleneck - Proverite da li je material complexity visok
- Proverite broj Nanite mesh instanci (CPU traversal cost)
- Proverite WPO koriscenje (moze da disabluje optimizacije)
Problem: Vizualni artefakti
- Tanki mesh-evi i single-sided geometrija mogu da imaju probleme
- Proverite da li mesh ima non-manifold geometriju (poglavlje 03)
- Za masked materijale, proverite da li opacity mask ima dovoljno osetar prelaz
30.13 Nanite internals: Dublje zaronjavajne
Za one koji zele dublje razumevanje, evo dodatnih tehnickih detalja o Nanite-ovim internijim mehanizmima.
Cluster group boundaries i crack-free LOD
Jedan od najtezih problema u per-cluster LOD sistemu je izbegavanje pukotina (cracks) na granicama izmedju klastera razlicitih LOD nivoa.
Zamislite dva susedna klastera: levi koristi LOD 0 (pun detalj), desni koristi LOD 2 (grub detalj). Na zajednickoj granici, levi klaster ima 20 verteksa, desni ima 5. Ako se verteksi ne poklapaju, nastaje pukotina -- vidljiv artifakt.
Nanite ovo resava sa locked boundary pristupom:
- Tokom klaster generacije, identifikuju se granicni verteksi -- verteksi koje deli dva ili vise klastera
- Tokom simplifikacije (LOD generacije), granicni verteksi se ne pomeraju i ne uklanjaju
- Time se garantuje da dva susedna klastera, ma kog LOD nivoa, uvek imaju identican red verteksa na zajednickoj granici
Ovo je elegantno resenje, ali ima implikaciju: povrsina mesh-a duz granica klastera moze da bude manje simplifikovana nego sto bi mogla da bude, jer su granicni verteksi "zakljucani". Nanite kompenzuje ovo inteligentnim klasterizovanjem koje minimizuje duzinu granica izmedju klastera.
DAG cut i konzistentnost
"Cut" kroz DAG (skup klastera koji je Nanite izabrao za renderovanje) mora da bude konzistentan -- mora da pokriva celu povrsinu mesh-a, bez rupa i bez preklapanja (osim minimalnog overlap-a na granicama).
Nanite obezbjedjuje ovo hijerarhijskim pravilom: za svaki cvor u DAG-u, ili se koristi sam cvor, ili se koriste sva njegova deca. Nikad ne moze da se desi da se koristi cvor i samo neka od njegove dece -- to bi izazvalo rupe ili dupliranje.
Persistent cluster ID-ovi
Svaki klaster u Nanite sistemu ima persistent ID koji se ne menja izmedju frejmova. Ovo je vazno za:
- Temporal stability: Vizualne efekte koji zavise od stabilnosti (TAA, motion blur) -- piksel koji prikazuje isti klaster u dva uzastopna frejma moze da iskoristi informacije iz prethodnog frejma
- Virtual Shadow Maps: VSM koristi Nanite cluster ID-eve za inkrementalno azuriranje senki -- samo klasteri koji su se promenili (ili se pomerili) zahtevaju re-renderovanje senki
Nanite i GPU-driven rendering
Nanite je deo sireg trenda u game rendering-u zvanog GPU-driven rendering -- pomeranje posla sa CPU-a na GPU. Tradicionalno, CPU je odlucivao sta da renderuje (traversal scene hijerarhije, LOD selekcija, culling) i slao draw call-ove GPU-u. Sa Nanite-om, znacajan deo ovog posla je prebacen na GPU:
- GPU culling: Frustum i occlusion culling na GPU-u
- GPU cluster selection: LOD selekcija na GPU-u
- Indirect draws: GPU sam odlucuje sta i koliko da renderuje
Ovo drasticno smanjuje CPU bottleneck i draw call overhead, sto je jedan od najvecih limitirajucih faktora u tradicionalnom renderovanju.
30.14 Nanite i buducnost
Nanite je u stalnom razvoju i svaka nova verzija UE5 donosi unapredjenja:
UE 5.0 (2022)
- Inicijalno izdanje Nanite-a
- Podrska za opaque static meshes
- Software i hardware rasterizer
- Streaming
UE 5.1
- Poboljsane performanse
- Bolja podrska za masked materijale
- Programmable rasterizer (mogucnost koriscenja custom materijala tokom rasterizacije)
UE 5.2
- Dodatna poboljsanja performansi
- Bolja streaming efikasnost
- Variable rate shading integracija
UE 5.3
- Poboljsana podrska za World Position Offset
- Performance optimizacije
UE 5.4+
- Nanite Tessellation: Runtime tessellation Nanite mesh-eva
- Landscape podrska (eksperimentalno)
- Napredak ka podrski za Skeletal Meshes
Buduci pravci
Nanite se krece u sledecim pravcima:
- Potpuna podrska za Skeletal Meshes: Ovo bi bilo ogromno za filmske i igracke produkcije
- Bolja vegetacija: Specijalizovana podrska za liscare i travu
- Proceduralna generacija: Integracija sa proceduralnim sistemima
- Hardware ray tracing integracija: Bolja interoperabilnost sa RT pipeline-om
- Smanjenje disk footprint-a: Kompresija Nanite podataka za manje projekat velicine
30.15 Cross-reference sa drugim poglavljima
Nanite ne postoji u izolaciji -- tesno je povezan sa mnogo drugih sistema koje smo obradili ili cemo obraditi:
Poglavlje 03: Mesh i topologija
Razumevanje mesh-eva, trouglova, verteksa i topologije je fundamentalno za razumevanje Nanite-a. Klasteri su grupe trouglova. LOD simplifikacija radi na mesh topologiji. Locked boundary verteksi su koncept iz topologije. Pogledajte poglavlje 03 za detalje o tome sta cini mesh i kako GPU cuva geometriju.
Poglavlje 09: Rasterizacija
Nanite-ov software rasterizer implementira istu matematiku kao hardverski rasterizer (edge equations, baricentricne koordinate), ali u compute shader-u. Visibility buffer koncept je predstavljen u poglavlju 09. Quad overdraw problem (koji Nanite software rasterizer resava) je detaljno obradjen u poglavlju 09.
Poglavlje 31: Virtual Shadow Maps
VSM je "sestarski" sistem Nanite-a -- koristi istu visibility buffer infrastrukturu za renderovanje senki sa enormnom rezolucijom. Nanite i VSM su dizajnirani da rade zajedno i dele mnoge interne strukture. Bez razumevanja Nanite-a, VSM je tesko razumeti.
Poglavlje 45: LOD optimizacija
Poglavlje 45 detaljno obraduje LOD strategije, ukljucujuci tradicionalne LOD-ove, HLOD (Hierarchical LOD), i kako Nanite menja LOD paradigmu. Ako vas zanima prakticna optimizacija geometrije u UE5, poglavlje 45 je obavezno citanje nakon ovog poglavlja.
Rezime kljucnih pojmova
| Pojam | Znacenje |
|---|---|
| Nanite | Epic-ov sistem virtualne geometrije u UE5 koji omogucava renderovanje masivnih kolicina poligona u realnom vremenu |
| Virtualna geometrija (Virtualized Geometry) | Pristup gde se geometrija apstrahuje slicno virtuelnoj memoriji -- samo potrebni delovi su ucitani u datom trenutku |
| Klaster (Cluster) | Grupa od ~128 trouglova koji su prostorno bliski; osnovna jedinica Nanite-ovog LOD sistema i renderovanja |
| DAG (Directed Acyclic Graph) | Hijerarhijska struktura podataka koja organizuje Nanite klastere u LOD nivoe; svaki cvor je klaster, ivice predstavljaju parent-child odnose izmedju LOD nivoa |
| Screen-space error | Mera razlike izmedju simplifikovanog i originalnog mesh-a, projicirana na ekran u pikselima; osnova za Nanite-ovu LOD selekciju |
| DAG traversal | Proces obilaska DAG hijerarhije za svaki frejm, od korena ka listovima, radi odabira optimalnih klastera |
| Software rasterizer | Nanite-ov custom rasterizer implementiran kao compute shader; efikasniji od hardverskog rasterizera za veoma sitne trouglove jer izbegava 2x2 quad overhead |
| Hardware rasterizer | Standardni GPU rasterizer (fixed-function); Nanite ga koristi za klastere sa vecim trouglovima gde je hardverska specijalizacija brza |
| Visibility Buffer | Buffer koji za svaki piksel cuva samo ID vidljivog trougla i baricentricne koordinate; razdvaja rasterizaciju od material evaluation |
| Material evaluation pass | Druga faza Nanite renderovanja gde se materijal evaluira tacno jednom po pikselu, na osnovu podataka iz visibility buffer-a |
| Streaming (geometrije) | Sistem koji dinamicki ucitava i oslobadja Nanite klastere sa diska, omogucavajuci scene sa vise podataka nego sto staje u VRAM |
| Virtual Geometry Pages | Stranice Nanite podataka koje se stream-uju sa diska, slicno stranicama virtuelne memorije |
| Streaming pool | Deo VRAM-a rezervisan za Nanite streaming podatke; konfigurise se sa r.Nanite.StreamingPool.SizeInMB |
| Locked boundary | Tehnika gde se granicni verteksi izmedju klastera zakljucavaju tokom simplifikacije, garantujuci crack-free LOD tranzicije |
| Frustum culling (per-cluster) | Odbacivanje klastera koji su van vidnog polja kamere; mnogo finija granularnost od per-mesh culling-a |
| Occlusion culling (per-cluster) | Odbacivanje klastera koji su zaklonjeni drugom geometrijom, koristeci Hi-Z buffer iz prethodnog frejma |
| Overdraw (Nanite) | Visestruko prepisivanje piksela tokom Nanite rasterizacije; jeftinije od tradicionalnog overdraw-a jer se material ne evaluira |
| Masked materijal | Blend mode koji koristi opacity mask za izrezivanje; podrzan u Nanite-u sa performance ogranicenjima |
| WPO (World Position Offset) | Materijalna tehnika pomeranja verteksa; podrzana u Nanite-u ali utice na culling efikasnost |
| Nanite Tessellation | Funkcionalnost (UE 5.4+) koja dodaje runtime tessellation Nanite mesh-evima za dodatni geometrijski detalj |
| GPU-driven rendering | Paradigma gde GPU preuzima poslove koji su tradicionalno bili na CPU-u (culling, LOD selekcija, draw call generisanje) |
| LOD (Level of Detail) | Tehnika smanjivanja kompleksnosti geometrije za udaljene objekte; Nanite automatizuje i kontinualizuje ovaj proces |
| HISM (Hierarchical Instanced Static Mesh) | UE5 sistem za efikasno renderovanje velikog broja instanci istog mesh-a; alternativa Nanite-u za masovnu sitniju geometriju |
Preporuceno citanje i resursi
Zvanicni Epic resursi
-
"Nanite -- A Deep Dive" (Brian Karis, SIGGRAPH 2021) -- Najdetaljnija tehnicka prezentacija o Nanite-ovim internals-ima, direktno od glavnog inzenjera. Obavezno citanje za svakoga ko zeli duboko razumevanje. Dostupno na:
https://advances.realtimerendering.com/s2021/ -
"Lumen in the Land of Nanite" tech demo -- Originalni demo koji je pokazao Nanite mogucnosti. Analizirajte ga u UE5 sa vizualizacionim modovima da vidite Nanite u akciji.
-
UE5 Nanite dokumentacija -- Oficijelna dokumentacija sa aktuelnim informacijama o podrzanim funkcionalnostima i ogranicenjima. Dostupno na:
https://dev.epicgames.com/documentation/en-us/unreal-engine/nanite-virtualized-geometry-in-unreal-engine
Tehnicke prezentacije
-
"A Deep Dive into Nanite Virtualized Geometry" (GDC 2024) -- Azurirane informacije o Nanite evoluciji u novijim verzijama UE5.
-
"The Road to Nanite" (Graham Wihlidal, Epic Games) -- Istorijski pregled razvoja Nanite-a i tehnickih izazova koji su reseni.
-
"GPU-Driven Rendering Pipelines" (SIGGRAPH Course) -- Siri kontekst GPU-driven renderinga u kome Nanite postoji.
Akademski radovi
-
"Mesh Simplification" (Michael Garland, Paul Heckbert, SIGGRAPH 1997) -- Fundamentalni rad o mesh simplifikaciji koji je osnova Nanite-ove LOD generacije.
-
"Cluster-based LOD" (vise autora) -- Raniji radovi o cluster-based pristupu LOD-u koji su inspirisali Nanite.
Knjige
- "Real-Time Rendering, 4th Edition" -- Poglavlja o LOD, rasterizaciji i GPU pipeline-u pruzaju kontekst neophodan za razumevanje inovacija koje Nanite donosi.
Zajednica
-
Unreal Engine Forums, Nanite sekcija -- Diskusije prakticnih problema i resenja sa Nanite-om.
-
Epic Games Dev Community -- Tehnicke diskusije i primeri projekata koji koriste Nanite.
U sledecem poglavlju prelazimo na Virtual Shadow Maps -- sistem senki koji je dizajniran da radi ruku pod ruku sa Nanite-om. Videcete kako VSM koristi Nanite-ovu visibility buffer infrastrukturu da pruzi senke sa nevidjenom rezolucijom i kvalitetom, bez klasicnih shadow map artefakata koje smo obradili u poglavlju 13.