Poglavlje 44: Occlusion i Culling
Uvod -- Zasto uopste ne renderovati nesto?
Zamislite da stojite u velikoj sobi i gledate kroz prozor ka gradu. Vidite nekoliko zgrada, deo ulice, mozda park u daljini. Ali iza vas su police sa knjigama, sto, stolice -- stvari koje ne vidite jer vam nisu u vidnom polju. Iza zgrada koje vidite kriju se jos desetine objekata koje takodje ne vidite jer ih nesto zaklanja. A daleko na horizontu postoje objekti koji su toliko mali na ekranu da ih je besmisleno renderovati u punoj rezoluciji.
GPU ne zna sta vi vidite. Ako mu kazete "renderiraj sve", on ce poslusno renderovati svaki poligon u sceni -- ukljucujuci one iza vas, one zaklanjene zidom i one na 5 kilometara udaljenosti koji zauzimaju jedan piksel na ekranu. Rezultat? Katastrofalni frame rate.
Culling (od engleskog to cull -- odbaciti, ukloniti) je skup tehnika kojima engine odredjuje koje objekte, mesh-eve ili cak individualne trouglove ne treba slati na renderovanje. Svaki objekat koji uspesno "cullujemo" je ustedjen posao za CPU (koji ne mora da priprema draw call) i GPU (koji ne mora da rasterizuje trouglove).
U ovom poglavlju prolazimo kroz sve glavne culling tehnike koje Unreal Engine 5 koristi, od najjednostavnijih do najnaprednijih:
- Frustum Culling -- ne renderuj ono sto je van vidnog polja kamere
- Distance Culling -- ne renderuj ono sto je predaleko
- Precomputed Visibility Volumes -- unapred izracunata vidljivost za staticne scene
- Software Occlusion Culling -- CPU-bazirano testiranje da li je objekat zaklonjen
- Hardware Occlusion Queries -- GPU upiti o vidljivosti objekata
- Nanite Occlusion Culling -- per-cluster GPU-driven culling za Nanite mesh-eve
Na kraju poglavlja, pogledacemo kako da debugujemo culling, prakticne strategije za razlicite tipove scena i zavrsicemo tabelom kljucnih pojmova.
Napomena o terminologiji: Kao i u ostatku knjige, tehnicke termine (frustum, occlusion, culling, bounding box, draw call, itd.) ostavljamo na engleskom jer su to standardni termini u game development industriji. Prevodjenje bi samo stvorilo konfuziju.
44.1 Zasto je Culling kriticno vazan za performanse
Pre nego sto zaronimo u konkretne tehnike, hajde da razumemo zasto je culling toliko bitan -- i za CPU i za GPU.
44.1.1 CPU strana price
Svaki objekat koji se renderuje prolazi kroz pipeline na CPU strani:
- Visibility determination -- da li je objekat vidljiv?
- Relevance checks -- da li je objekat dovoljno blizu/vazan da se renderuje?
- Draw call preparation -- priprema podataka za GPU (materijali, transformacije, shader parametri)
- Command buffer submission -- slanje komandi GPU-u
Koraci 3 i 4 su skupi. Svaki draw call ima overhead na CPU strani. Ako imate scenu sa 50.000 objekata, a samo 2.000 je vidljivo, culling vam stedi pripremu 48.000 draw call-ova. To moze da bude razlika izmedju 60 FPS i 15 FPS.
44.1.2 GPU strana price
Na GPU strani, svaki trougao koji se renderuje prolazi kroz:
- Vertex Shader -- transformacija svake tacke trougla
- Rasterization -- pretvaranje trougla u fragmente (piksele)
- Fragment/Pixel Shader -- izracunavanje boje svakog piksela
- Depth test, blending, write -- zavrsna obrada
Ako renderujete 10 miliona trouglova koji su iza zida i nece se nikada videti na ekranu, GPU radi ogroman posao uzalud. Culling eliminise taj nepotrebni posao.
44.1.3 Overdraw problem
Cak i kada objekat jeste u vidnom polju, ako je kompletno zaklonjen drugim objektom (recimo, ormar iza zida), renderovanje tog ormara je cist gubitak. GPU ce izracunati boju svakog piksela ormara, samo da bi depth test rekao "nema potrebe, vec postoji blizi piksel". Ovo se zove overdraw i jedan je od glavnih neprijatelja performansi u kompleksnim scenama.
44.1.4 Масштаб проблема у великим scenama
U malim scenama (recimo, jedna soba sa 50 objekata), culling nije kritican -- GPU moze da se nosi i bez njega. Ali u modernim igrama situacija je drasticno drugacija:
| Tip scene | Tipican broj objekata | Bez cullinga | Sa cullingom |
|---|---|---|---|
| Mala soba | 50-200 | Radi OK | Minimalan uticaj |
| Grad (jedan blok) | 5.000-20.000 | Problematicno | Neophodno |
| Open world (1 km2) | 100.000-500.000 | Neigrajivo | Kriticno |
| AAA open world | 1.000.000+ | Nemoguce | Apsolutno neophodno |
Kao sto vidite, sto je scena veca, culling postaje vazniji. U open world igrama, culling je bukvalno razlika izmedju igre koja radi i igre koja se ne moze pokrenuti.
44.2 Frustum Culling -- Osnova svega
44.2.1 Sta je View Frustum?
Ako ste citali Poglavlje 06 (gde smo detaljno objasnili frustum), znate da je view frustum (vidna piramida) oblik koji opisuje sta kamera "vidi". To je zarubljena piramida (truncated pyramid) definisana sa sest ravni:
- Near plane -- najbliza ravan kameri
- Far plane -- najdalja ravan kameri
- Left, Right, Top, Bottom planes -- bocne ravni
Sve sto je unutar ovog volumena je potencijalno vidljivo. Sve sto je van njega definitivno nije vidljivo i moze se bezbedno preskociti.
44.2.2 Kako frustum culling radi
Algoritam je konceptualno jednostavan:
Za svaki objekat u sceni:
1. Uzmi bounding volume objekta (obicno AABB ili sphere)
2. Testiraj da li bounding volume preseca view frustum
3. Ako NE preseca --> CULL (ne renderuj)
4. Ako preseca --> DRAW (renderuj)
Test "da li bounding volume preseca frustum" se svodi na testiranje objekta protiv sest ravni frustuma. Objekat je van frustuma ako je kompletno sa spoljasnje strane bilo koje od sest ravni.
Za Axis-Aligned Bounding Box (AABB) -- koji smo detaljno objasnili u Poglavlju 03 -- test se radi tako sto se za svaku ravan frustuma proveri da li su svih 8 tacaka AABB-a sa spoljasnje strane. Ako jesu, objekat je van frustuma.
Za Bounding Sphere je jos jednostavnije -- proverava se da li je centar sfere udaljen od ravni vise od radijusa sfere.
44.2.3 Frustum Culling u UE5 -- automatski i besplatan
Odlicna vest: frustum culling je automatski ukljucen u UE5 i ne morate nista posebno da radite da biste ga aktivirali. Engine ga izvrsava za svaki frame, za svaki objekat u sceni.
UE5 koristi hijerarhijsku strukturu za ubrzanje frustum testova. Umesto da testira svaki objekat individualno (sto bi bilo O(n) za n objekata), engine koristi prostorne strukture podataka koje omogucavaju brzo odbacivanje velikih grupa objekata odjednom.
44.2.4 Znacaj velicine Bounding Box-a
Ovo je cesto zanemarena ali izuzetno vazna tema. Velicina bounding box-a direktno utice na efikasnost frustum cullinga.
Problem prevelikog bounding box-a:
Zamislite da imate mesh koji je dugacka, tanka cijev -- recimo, 50 metara duga a 10 cm siroka. Njen AABB ce biti kutija od 50 x 0.1 x 0.1 metara. Ako je ta cijev dijagonalno postavljena u sceni, AABB ce zapravo biti mnogo veci -- recimo 35 x 35 x 0.1 metara -- jer AABB mora da bude poravnat sa osama koordinatnog sistema.
Sta to znaci u praksi? Taj objekat ce reze biti culled jer njegov bounding box ulazi u frustum cak i kada sam mesh nije vidljiv.
Prakticni saveti:
- Ne pravite ogromne monolitne mesh-eve. Mesh koji pokriva celu zgradu ce imati ogroman bounding box i gotovo nikada nece biti culled.
- Razbijte velike mesh-eve na logicne delove. Svaki sprat zgrade, svaki zid, svaka soba moze biti poseban mesh sa sopstvenim bounding box-om.
- Pazite na "nevidljive" delove mesh-a. Ponekad mesh ima vertex-e koji su daleko od vidljivog dela (npr. pivot point koji je na pogresnom mestu). Ovo nepotrebno povecava bounding box.
- Koristite
Bounds Scaleproperty na Actor-u da skaliranje bounding box-a bude tacnije (ali budite pazljivi -- premali bounds moze da dovede do toga da se objekat culled kada ne bi trebalo, sto izgleda kao "popping").
// U UE5, svaki Actor ima Bounds Scale property
// Default je 1.0. Mozete ga podesiti u Details panelu.
// Veci broj = veci bounding box = manje agresivan culling
// Manji broj = manji bounding box = agresivniji culling (ali rizik od poppinga)
44.2.5 Frustum Culling i visestruke kamere
Frustum culling se izvrsava za svaku kameru posebno. Ovo je relevantno u nekoliko situacija:
- Split-screen multiplayer -- svaki igrac ima svoj frustum
- Security camera/minimap renderovanje -- svaka dodatna kamera zahteva svoj culling pass
- Shadow map renderovanje -- svaki shadow-casting light ima svoj frustum za shadow map
- Reflection captures -- capture komponente imaju sopstveni frustum
Zbog toga, smanjenje broja kamera koje aktivno renderuju scenu moze znacajno da poboljsa performanse -- ne samo zbog samog renderovanja, vec i zbog visestrukih culling pass-ova.
44.3 Distance Culling -- Ne renderuj predaleke objekte
44.3.1 Koncept
Distance culling je jednostavna ali mocna tehnika: ako je objekat dalje od odredjene udaljenosti od kamere, ne renderuj ga. Logika je da objekti koji su veoma daleko zauzimaju mali broj piksela na ekranu i njihovo renderovanje donosi minimalan vizuelni doprinos, a kosta draw call.
44.3.2 Per-Actor Cull Distance u UE5
Svaki Actor u UE5 ima property koji se zove Min Draw Distance i implicitno koristi Max Draw Distance (koji se moze podesiti kroz Cull Distance Volume, o cemu cemo pricati u narednoj sekciji).
Da biste podesili per-actor cull distance:
- Selektujte Actor u sceni
- U Details panelu, pronadjite sekciju Rendering
- Podesiti
Desired Max Draw Distance-- ovo je rastojanje (u UE jedinicama, tj. centimetrima) nakon kojeg ce Actor biti culled
// Primer: Actor koji nestaje na 5000 UE jedinica (50 metara)
MyActor->SetCullDistance(5000.0f);
// Ili u Details panelu:
// Desired Max Draw Distance: 5000
Vazna napomena: Desired Max Draw Distance je "zelja" Actora. Ako postoji Cull Distance Volume koji pokriva taj deo scene i ima strozi (manji) max draw distance za tu kategoriju velicine, Volume ce "pobediti" i Actor ce biti culled ranije.
44.3.3 Cull Distance Volumes
Cull Distance Volume je poseban Volume actor u UE5 koji vam omogucava da definisete pravila za distance culling na nivou citave oblasti scene.
Kako funkcionise
Cull Distance Volume sadrzi tabelu koja mapira velicinu objekta na maksimalnu udaljenost renderovanja:
| Velicina objekta (Bounding Sphere Radius) | Max Draw Distance |
|---|---|
| 0 - 100 | 5.000 |
| 100 - 500 | 15.000 |
| 500 - 1.000 | 30.000 |
| 1.000 - 5.000 | 50.000 |
| 5.000+ | 0 (nikada ne culluj) |
Logika je intuitivna: manji objekti se culluju na manjoj udaljenosti jer zauzimaju manje piksela na ekranu i manje se primecuju kada nestanu. Veliki objekti (zgrade, planine) se culluju na vecoj udaljenosti ili uopste ne.
Kreiranje Cull Distance Volume-a
- U Place Actors panelu, pronadjite Cull Distance Volume
- Postavite ga u scenu i skalirajte da pokrije zeljenu oblast
- Selektujte Volume i u Details panelu pronadjite Cull Distances niz
- Dodajte parove
(Size, Cull Distance):Size= radijus bounding sphere objektaCull Distance= maksimalna udaljenost renderovanja
// Primer konfiguracije Cull Distance Volume-a:
// (ovo se obicno radi u editoru, ali moze i programski)
// Size: 50, CullDistance: 3000 // Mali objekti (flase, knjige)
// Size: 200, CullDistance: 10000 // Srednji objekti (stolice, stolovi)
// Size: 500, CullDistance: 25000 // Veci objekti (automobili)
// Size: 1000, CullDistance: 50000 // Veliki objekti (kuce)
// Size: 5000, CullDistance: 0 // Ogromni objekti (nikad ne culluj)
Visestruki Cull Distance Volumes
Mozete imati vise Cull Distance Volume-a u sceni koji se preklapaju. Kada se Actor nalazi unutar vise Volume-a, koristi se najmanji (najstrozi) cull distance. Ovo vam omogucava da imate razlicita pravila za razlicite delove scene:
- U gusto naseljenom gradu, agresivniji culling (manji max distances)
- U otvorenom krajoliku, manje agresivan culling (veci max distances) jer igrac moze da vidi daleko
44.3.4 Distance Culling i World Partition
Ako koristite World Partition sistem (detaljno obradjen u Poglavlju 32), distance culling i streaming rade zajedno:
- World Partition streaming kontrolise koji delovi sveta su uopste ucitani u memoriju
- Distance culling kontrolise koji od ucitanih objekata se renderuju
Ovo su dva razlicita sistema koji se dopunjuju. Objekat moze biti ucitan u memoriju (jer je u streaming distance-u) ali se ne renderuje (jer je van cull distance-a). Ovo je korisno jer ucitavanje u memoriju nije instant -- potrebno je vreme za streaming -- pa zelite da objekti budu spremni pre nego sto postanu vidljivi.
44.3.5 HLOD i Distance Culling
Hierarchical Level of Detail (HLOD) je sistem gde se grupa objekata na velikoj udaljenosti zamenjuje jednim pojednostavljenim mesh-om. Ovo je komplementarno sa distance cullingom:
- Na bliskoj udaljenosti: puni detalji, individualni objekti
- Na srednjoj udaljenosti: LOD-ovi (manje detaljan mesh za svaki objekat)
- Na velikoj udaljenosti: HLOD (jedan mesh za grupu objekata)
- Na ogromnoj udaljenosti: distance cull (nista se ne renderuje)
44.4 Precomputed Visibility Volumes
44.4.1 Ideja iza Precomputed Visibility
Frustum culling i distance culling su "jeftine" provere, ali ne resavaju problem occlusion-a -- objekat moze biti unutar frustuma i dovoljno blizu, ali kompletno zaklonjen zidom. Da bismo utvrdili da li je objekat zaklonjen, potrebna je skuplja analiza.
Precomputed Visibility je tehnika gde se offline (pre pokretanja igre, tokom build procesa) izracunava koja oblast scene vidi koje objekte. Rezultati se cuvaju u baked podatke i koriste tokom runtime-a za brzu pretragu.
44.4.2 Kako funkcionise
- Podela prostora na celije: Scena se deli na 3D grid celija (obicno 200x200x200 UE jedinica)
- Visibility sampling: Za svaku celiju, engine izracunava koje objekte ta celija moze da vidi (slanjem zraka ili koristeci PVS -- Potentially Visible Set algoritme)
- Cuvanje rezultata: Rezultat je bitmaska za svaku celiju -- za svaki objekat, jedan bit koji kaze "vidljiv" ili "nevidljiv"
- Runtime lookup: Tokom igre, engine proverava u kojoj celiji se kamera nalazi i koristi precomputed bitmasku da brzo iskljuci nevidljive objekte
44.4.3 Postavljanje u UE5
- Postavite
Precomputed Visibility Volumeu scenu (Place Actors > Volumes > Precomputed Visibility Volume) - Skalirajte Volume da pokrije oblast gde zelite precomputed visibility
- U World Settings, podesiti:
Precompute Visibility: TrueVisibility Cell Size: Velicina celije (default 200). Manji = precizniji ali vise memorijeVisibility Aggressiveness: Koliko agresivno se odbacuju objekti
- Build Lighting (ili Precompute Visibility odvojeno) -- ovo je offline proces koji moze trajati od minuta do sati, zavisno od velicine scene
// World Settings podesavanja:
// Precompute Visibility: True
// Visibility Cell Size: 200 (default)
// Visibility Aggressiveness:
// - Least Aggressive (0) -- konzervativno, manje false negatives
// - Most Aggressive (3) -- agresivno, brze ali rizik od poppinga
44.4.4 Kada koristiti Precomputed Visibility
Idealno za:
- Zatvorene (indoor) scene -- zidovi jasno razdvajaju vidljive od nevidljivih objekata
- Scene sa mnogo occlusion-a -- gradovi sa uskim ulicama, lavirinti, zgrade sa mnogo soba
- Staticne scene -- objekti se ne pomeraju (Precomputed Visibility radi samo sa staticnim objektima)
Nije idealno za:
- Otvorene scene sa malo occlusion-a -- u otvorenom polju vecina objekata je vidljiva iz vecine pozicija
- Scene sa mnogo dinamickih objekata -- precomputed podaci ne pokrivaju objekte koji se pomeraju
- Veoma velike scene -- memorijski zahtevi mogu biti preveliki (svaka celija cuva bitmasku za svaki objekat)
44.4.5 Ogranicenja
- Radi samo sa staticnim objektima (Static Mobility)
- Zahteva offline build -- svaka promena scene zahteva rebuild
- Memorijski overhead moze biti znacajan za velike scene
- Ne pokriva dinamicke objekte (neprijatelje, vozila, itd.)
44.5 Software Occlusion Culling
44.5.1 Koncept
Software Occlusion Culling je tehnika gde CPU renderuje pojednostavljenu verziju scene (obicno samo dubinu/depth) u mali buffer i zatim testira objekte protiv tog depth buffer-a da utvrdi da li su zaklanjeni.
Zamislite to ovako: CPU nacrta "skicu" scene u maloj rezoluciji (recimo 256x256 piksela), i onda za svaki objekat pita "da li bi ovaj objekat bio vidljiv ili je nesto ispred njega?"
44.5.2 Kako radi u UE5
UE5 ima ugradjeni Software Occlusion system:
- Occluder meshevi se renderuju u mali depth buffer na CPU-u
- Za svaki objekat koji treba da se testira, njegov bounding box se projektuje na taj depth buffer
- Ako je bounding box kompletno "iza" vec renderovanih piksela u depth bufferu, objekat je zaklonjen i moze se preskociti
// Aktiviranje Software Occlusion Culling-a:
// U Project Settings > Engine > Rendering:
// Software Occlusion Culling: True
// Ili u konzoli:
r.SO.Enable 1
// Podesavanje rezolucije depth buffer-a:
r.SO.BufferSize 256 // default
44.5.3 Prednosti
- Nema latencije -- rezultati su dostupni odmah, u istom frame-u
- Radi sa svim objektima -- ne zahteva poseban hardware support
- Kompatibilno sa svim rendering putanjama -- radi i sa forward i sa deferred renderingom
- Predvidive performanse -- CPU cost je konzistentan i predvidiv
44.5.4 Mane
- CPU cost -- renderovanje depth buffer-a na CPU-u nije besplatno
- Ogranicena preciznost -- mali depth buffer znaci da se mali objekti mozda nece pravilno testirati
- Pojednostavljena geometrija -- koriste se proxy mesh-evi, sto moze dovesti do nepreciznih rezultata
- Skaliranje -- za scene sa mnogo objekata, CPU cost moze da postane prevelik
44.5.5 Kada koristiti
Software Occlusion je koristan za:
- Mobilne platforme gde hardware occlusion queries mogu biti problematicne
- Scene sa velikim occluder-ima (zidovi, zgrade) koji efikasno zaklanjaju mnogo manjih objekata
- Situacije gde vam je potreban occlusion bez latencije (za razliku od hardware occlusion queries)
44.6 Hardware Occlusion Queries
44.6.1 Koncept
Hardware Occlusion Queries koriste GPU da testira da li je objekat vidljiv. Ideja je:
- Renderuj bounding box objekta kao "query" -- ne crta se na ekran, vec se samo pita GPU "da li bi bilo koji piksel ovog bounding box-a prosao depth test?"
- GPU izvrsi test i vrati rezultat: broj piksela koji bi prosli depth test
- Ako je taj broj 0 (ili ispod nekog praga), objekat je zaklonjen
44.6.2 Kako funkcionise u praksi
// Pseudo-kod hardware occlusion query:
// Frame N:
1. GPU renderuje scenu normalno
2. Za objekte koji su kandidati za occlusion testing:
a. Posalji GPU-u query: "Renderuj bounding box objekta X, koliko piksela prolazi?"
b. GPU izvrsi test (ali ne crta na ekran)
// Frame N+1 (ili N+2):
3. CPU cita rezultate query-ja iz prethodnog frame-a
4. Ako je broj vidljivih piksela == 0:
--> Objekat je zaklonjen, ne renderuj ga u ovom frame-u
5. Ako je broj vidljivih piksela > 0:
--> Objekat je vidljiv, renderuj ga
44.6.3 Problem latencije -- Kljucni izazov
Primijetili ste problem u pseudo-kodu iznad? GPU query iz frame-a N se ne moze procitati u frame-u N. Rezultat je dostupan tek u frame-u N+1 ili cak N+2. Ovo je zato sto:
- GPU radi asinhrono u odnosu na CPU
- Postoji pipeline od nekoliko frame-ova izmedju CPU slanja komande i GPU zavrsavanja
- Citanje rezultata query-ja zahteva sinhronizaciju izmedju CPU i GPU, sto je skupo
Ova latencija od 1-2 frame-a stvara problem: koristimo zastarele podatke da odlucimo sta da renderujemo. Ako se kamera brzo pomeri, objekat koji je bio zaklonjen u frame-u N moze da postane vidljiv u frame-u N+2, ali mi smo ga vec odlucili preskociti. Rezultat: objekat "blinkne" na ekranu -- pojavi se frame kasnje nego sto bi trebalo.
44.6.4 Strategije za ublazavanje latencije
UE5 koristi nekoliko strategija da ublazi ovaj problem:
1. Konzervativno testiranje: Umesto tacnog bounding box-a, koristi se malo veci bounding box za occlusion query. Ovo znaci da ce objekat "postati vidljiv" malo ranije nego sto zaista treba, cime se smanjuje rizik od poppinga.
2. "Render if uncertain" pristup: Ako nema rezultata query-ja (npr. prvi frame), objekat se renderuje. Bolje je renderovati nepotreban objekat nego propustiti vidljiv objekat.
3. Multi-frame amortizacija: Ne testiraju se svi objekti u svakom frame-u. Objekat se testira jednom i rezultat se koristi nekoliko frame-ova, a zatim se ponovo testira. Ovo smanjuje broj query-ja ali povecava latenciju za neke objekte.
4. Temporal coherence: Pretpostavka je da se vidljivost objekta ne menja drasticno iz frame-a u frame. Ako je objekat bio vidljiv u prethodnom frame-u, verovatno je i dalje vidljiv. Ova heuristika uglavnom radi dobro, osim kod brzih pokreta kamere.
44.6.5 Hardware Occlusion Queries u UE5
// Kontrola Hardware Occlusion Queries u UE5:
// Ukljucivanje/iskljucivanje:
r.HZBOcclusion 1 // Hierarchical Z-Buffer occlusion (default ON)
r.AllowOcclusionQueries 1 // Hardware occlusion queries
// Podesavanje agresivnosti:
r.HZBOcclusion.MaxPixelThreshold 4 // Min piksela da se smatra vidljivim
Hierarchical Z-Buffer (HZB) Occlusion je napredna varijanta hardware occlusion-a koju UE5 koristi. Umesto individualnih query-ja za svaki objekat, HZB kreira hijerarhiju depth buffer-a (mipmap lanac depth texture-a) i testira objekte protiv njega. Ovo je efikasnije jer:
- Smanjuje broj individualnih GPU query-ja
- Omogucava paralelno testiranje mnogo objekata
- Koristi vec postojeci depth buffer iz prethodnog renderovanja
44.6.6 Prednosti i mane
Prednosti:
- Veoma tacno testiranje -- GPU radi pravi depth test
- Radi sa dinamickim objektima -- nista nije precomputed
- Moze da detektuje occlusion od bilo kog objekta, ne samo od predefinisanih occluder-a
Mane:
- Latencija -- rezultati kasne 1-2 frame-a
- GPU overhead -- svaki query zauzima GPU resurse
- CPU-GPU sinhronizacija -- citanje rezultata moze da blokira CPU
- Efikasnost opada sa brojem objekata -- previse query-ja moze da bude kontraproduktivno
44.7 Nanite Occlusion Culling -- Revolucija u culling-u
44.7.1 Sta Nanite menja
Nanite, Unreal Engine 5 virtualized geometry system (detaljno obradjen u Poglavlju 30), donosi fundamentalno drugaciji pristup occlusion culling-u. Umesto da radi na nivou celih mesh-eva, Nanite radi occlusion culling na nivou klastera (grupa trouglova).
44.7.2 Per-Cluster GPU-Driven Culling
Nanite mesh je interno podeljen na klastere -- male grupe od otprilike 128 trouglova. Svaki klaster ima svoj bounding box. Nanite culling pipeline radi ovako:
Za svaki Nanite mesh u sceni:
Za svaki klaster u mesh-u (moze ih biti hiljade):
1. Instance Culling -- da li je instanca uopste relevantna?
2. Frustum Culling -- da li je klaster u frustumu?
3. HZB Occlusion Culling -- da li je klaster zaklonjen?
4. Screen-size Culling -- da li je klaster dovoljno veliki na ekranu?
5. Ako prodje sve testove --> renderuj klaster
6. Ako padne na bilo kom testu --> preskoci klaster
Kljucna razlika: Ceo ovaj pipeline se izvrsava na GPU-u, ne na CPU-u. Ovo eliminise:
- CPU bottleneck od visibility testiranja
- Latenciju izmedju CPU i GPU
- Ogranicenje broja objekata koje CPU moze da obradi
44.7.3 Two-Pass Occlusion Culling
Nanite koristi dvoradni (two-pass) pristup occlusion culling-u koji elegantno resava problem latencije:
Pass 1 -- Prethodni frame test:
- Koristi HZB (Hierarchical Z-Buffer) iz prethodnog frame-a
- Testira sve klastere protiv tog HZB-a
- Klasteri koji su bili vidljivi u prethodnom frame-u se renderuju
- Klasteri koji su mozda zaklanjeni se stavljaju u "uncertain" listu
Pass 2 -- Trenutni frame test:
- Iz renderovanih klastera iz Pass 1, generise se novi HZB za trenutni frame
- "Uncertain" klasteri se testiraju protiv ovog novog HZB-a
- Klasteri koji prolaze test se dodatno renderuju
- Klasteri koji ne prolaze su zaista zaklanjeni
Ovaj two-pass pristup obezbedjuje:
- Nema poppinga -- objekti koji postanu vidljivi se uhvate u Pass 2
- Minimalna latencija -- sve se desava unutar jednog frame-a
- Efikasnost -- vecina klastera se resi u Pass 1 (jer se vidljivost retko drasticno menja)
44.7.4 Screen-Size Culling u Nanite
Osim occlusion-a, Nanite takodje radi screen-size culling -- ako bi klaster zauzimao manje od odredjenog broja piksela na ekranu, preskace se. Ovo je automatski LOD sistem na nivou klastera:
- Blizu kamere: svi klasteri su dovoljno veliki, puna geometrija
- Dalje od kamere: manji klasteri se preskacaju, automatski LOD
- Veoma daleko: samo najgrublji klasteri ostaju
Ovo je ekvivalentno distance culling-u, ali mnogo finijeg granulariteta -- umesto da ceo mesh nestane, postepeno se smanjuje detalj.
44.7.5 Nanite vs. tradicionalni culling
| Aspekt | Tradicionalni Culling | Nanite Culling |
|---|---|---|
| Granularnost | Per-mesh (ceo objekat) | Per-cluster (~128 trouglova) |
| Izvrsavanje | CPU | GPU |
| Latencija | 1-2 frame-a (HW queries) | 0 frame-ova (two-pass u istom frame-u) |
| LOD | Diskretni LOD nivoi | Kontinualan, per-cluster |
| Setup | Rucno (cull distances, volumes) | Automatski |
| Ogranicenja | Mesh mora biti Static | Mora biti Nanite-enabled mesh |
44.7.6 Sta Nanite ne pokriva
Vazno je razumeti da Nanite culling radi samo za Nanite-enabled mesh-eve. Ostali objekti (skeletal meshevi, particle sistemi, non-Nanite static meshevi) i dalje koriste tradicionalne culling metode. Zato je poznavanje svih culling tehnika i dalje vazno.
44.8 Prakticne strategije za razlicite tipove scena
44.8.1 Velika Open World scena
Open world scene su najzahtevniji slucaj za culling. Imate potencijalno milione objekata rasprostranjene na ogromnoj povrsini, sa razlicitim zonama (gradovi, sume, polja, planine).
Strategija:
-
World Partition za streaming (videti Poglavlje 32):
- Podelite svet na celije odgovarajuce velicine
- Podesite streaming distance da ucitavate samo relevantne celije
- Koristite Data Layers za razlicite kategorije objekata
-
Cull Distance Volumes za razlicite zone:
- Gradski delovi: agresivniji culling (vise objekata, manje vidljivosti na daljinu)
- Otvoreni tereni: manje agresivan culling (manje objekata, vise vidljivosti)
- Sume: srednje agresivan (drvece zaklanja, ali je manje gusto nego grad)
-
HLOD za daleke objekte:
- Generisati HLOD za grupe objekata (npr. ceo blok zgrada postaje jedan simplified mesh)
- HLOD se prikazuje na velikoj udaljenosti, a individualni objekti na maloj
-
Nanite za detaljnu geometriju:
- Sve staticke mesh-eve koji to podrzavaju konvertovati u Nanite
- Pustiti Nanite da automatski upravlja LOD-om i per-cluster cullingom
-
Per-Actor cull distance za specificne kategorije:
- Sitni objekti (kamenice, trava, smece): mali cull distance (2.000-5.000)
- Srednji objekti (klupe, znakovi, drvo): srednji cull distance (10.000-20.000)
- Veliki objekti (zgrade, stene): veliki cull distance (50.000+) ili bez distance cullinga
Primer podesavanja za open world:
// Console komande za fine-tuning:
// Podesavanje minimalnog screen size-a za renderovanje
r.SkeletalMesh.ScreenSizeScale 1.0
r.StaticMesh.ScreenSizeScale 1.0
// Nanite culling podesavanja
r.Nanite.MaxPixelsPerEdge 1.0 // Kontrolise LOD agresivnost
// Foliage culling
foliage.CullDistanceScale 1.0 // Globalni skaler za foliage cull distance
foliage.MinimumScreenSize 0.001 // Minimalni screen size za foliage
44.8.2 Gusta interior scena (zgrade, dungeon-i)
Interior scene su obicno najpogodnije za occlusion culling jer zidovi efikasno zaklanjaju objekte. Kljucne strategije:
Strategija:
-
Precomputed Visibility je idealan:
- Postavite Precomputed Visibility Volume preko cele zgrade
- Koristite manji Cell Size (100-150) za preciznije rezultate
- Rebuild posle svake promene geometrije
-
Pravilna podela geometrije:
- Svaka soba treba da bude poseban mesh (ili grupa mesh-eva)
- Zidovi izmedju soba treba da budu dobri occluder-i
- Izbegavajte jedan veliki mesh za ceo sprat
-
Portali i logicko razdvajanje:
- Vrata su prirodni "portali" -- objekti u susednoj sobi su vidljivi samo ako su vrata otvorena i kamera gleda ka njima
- UE5 nema explicit portal system kao neki drugi engine-i, ali Precomputed Visibility i HZB occlusion postizu slican efekat
-
Pazi na providne objekte:
- Staklo, reshetke i drugi providni/poluprozirni objekti komplikuju occlusion jer ne zaklanjaju u potpunosti
- Razmislite da li providni objekti treba da budu occluder-i ili ne
Primer organizacije interior scene:
// Struktura interior scene:
// Building_01/
// Floor_01/
// Room_01_Walls (Static Mesh, occluder)
// Room_01_Floor (Static Mesh)
// Room_01_Furniture/ (grupa manjih objekata)
// Chair_01
// Table_01
// Lamp_01
// Room_01_Door (moze biti dinamicna)
// Floor_02/
// Room_02_Walls
// ...
// Svaka soba ima sopstveni bounding box
// Zidovi efektivno zaklanjaju objekte u susednim sobama
// Precomputed Visibility koristi ovu strukturu za efikasan culling
44.8.3 Hibridne scene (spoljasnjost + unutrasnjost)
Mnoge moderne igre imaju scene gde igrac moze slobodno da prelazi izmedju spoljasnjosti (open world) i unutrasnjosti (zgrade). Ovo je najslozeniji slucaj.
Strategija:
-
Kombinujte tehnike:
- Koristite Precomputed Visibility za interijere
- Koristite Cull Distance Volumes za eksterijere
- Koristite Nanite za detaljnu staticku geometriju svuda
-
World Partition + Interior streaming:
- Interijer zgrade ne mora da bude ucitan dok igrac nije u blizini
- Koristite Level Instances ili Data Layers za kontrolu ucitavanja interijera
-
Posebna paznja na prelaze:
- Kada igrac gleda spolja kroz prozor, vidi se deo interijera -- ovo mora da radi bez poppinga
- Kada igrac izadje iz zgrade, ceo grad treba da bude vec spreman
- Streaming distance za interijer treba da bude dovoljno veliki da pokrije ove prelaze
44.8.4 Scene sa mnogo instanci (sume, gradovi)
Kada imate hiljade instanci istog mesh-a (drvece, zgrade u gridu), Instanced Static Mesh ili Hierarchical Instanced Static Mesh (HISM) komponente pomazu culling-u:
- HISM interno organizuje instance u stablo (tree structure)
- Frustum i distance culling se rade hijerarhijski -- cela grana stabla se moze odbaciti odjednom
- Ovo je mnogo efikasnije od individualnog testiranja svake instance
// Foliage sistem u UE5 automatski koristi HISM
// Za custom instanciranje, koristite HISM komponentu:
UHierarchicalInstancedStaticMeshComponent* HISMComp =
NewObject<UHierarchicalInstancedStaticMeshComponent>(this);
HISMComp->SetStaticMesh(MyMesh);
// Dodavanje instanci:
for (int32 i = 0; i < NumInstances; i++)
{
FTransform Transform;
Transform.SetLocation(FVector(i * 100.0f, 0.0f, 0.0f));
HISMComp->AddInstance(Transform);
}
// HISM ce automatski organizovati instance za efikasan culling
44.9 Debugging Culling-a
Znati da culling postoji je jedno -- znati da li radi pravilno u vasoj sceni je sasvim drugo. UE5 nudi nekoliko alata za debugovanje culling-a.
44.9.1 FreezeRendering komanda
Ovo je najkorisniji alat za debugovanje culling-a. Komanda FreezeRendering zamrzava renderovanje u trenutnom stanju -- scena nastavlja da se renderuje kao da je kamera na poziciji gde ste je zamrzli, ali mozete slobodno da se kresite po sceni i vidite koji objekti su renderovani a koji nisu.
Kako koristiti:
- Pozicionirajte kameru gde zelite da analizirate culling
- Otvorite konzolu (tilda
~) i ukucajte:FreezeRendering - Sada mozete da se kresite po sceni. Objekti koji su culled ce nedostajati -- videcete "rupe" u sceni gde bi objekti trebali da budu
- Da odmrznete renderovanje:
(ista komanda toggleuje)FreezeRendering
Sta traziti:
- Da li se svi ocekivani objekti renderuju? Ako nedostaju objekti koji bi trebali da budu vidljivi, culling je previse agresivan
- Da li se renderuju objekti koji ne bi trebali? Ako vidite objekte koji su iza zida, occlusion culling ne radi optimalno
- Koliko objekata je renderovano? Koristite
stat scenerenderingda vidite brojeve
44.9.2 Wireframe pogled
Wireframe pogled vam omogucava da vidite sve renderovane objekte kao zicane modele, bez popunjenih povrsina. Ovo je korisno jer mozete lakse uociti preklapanja i nepotrebno renderovane objekte.
Aktiviranje:
- U Viewport-u, kliknite na "Lit" dropdown i izaberite Wireframe
- Ili pritisnite Alt+2 (shortcut za wireframe mode)
- Ili u konzoli:
viewmode wireframe
Kombinacija sa FreezeRendering:
- Ukljucite wireframe mode
- Pozicionirajte kameru
- Ukucajte
FreezeRendering - Predjite na normalan pogled (Alt+4 za Lit mode)
- Sada mozete da se kresite i vidite koji objekti se renderuju (oni koji su vidljivi) a koji ne (oni koji nedostaju jer su culled)
44.9.3 Stat komande za culling
UE5 ima nekoliko stat komandi koje prikazuju statistike relevantne za culling:
// Opste renderovanje statistike:
stat scenerendering
// Prikazuje: Mesh draw calls, primitives drawn, itd.
// Kljucni brojevi:
// - "Mesh Draw Calls" -- koliko draw call-ova imate
// - "Visible Static Mesh Elements" -- vidljivi elementi
// - "Culled primitives" -- koliko je primitiva culled
// Inicijalizacija scene:
stat initviews
// Prikazuje: Frustum culling vreme, occlusion culling vreme
// Kljucni brojevi:
// - "Frustum Cull" -- vreme utroseno na frustum culling
// - "Occlusion Cull" -- vreme za occlusion queries
// - "View Relevance" -- vreme za odredjivanje relevantnosti
// Nanite statistike:
stat Nanite
// Prikazuje: Nanite-specificne metrike
// Kljucni brojevi:
// - "Visible Clusters" -- koliko klastera se renderuje
// - "Total Clusters" -- ukupan broj klastera u sceni
// - "Culled Clusters" -- koliko je klastera culled
44.9.4 Vizualizacija Bounding Box-ova
Da biste videli bounding box-ove objekata u sceni:
// Prikaz bounding box-ova:
show bounds
// Ili specificno za static mesh-eve:
r.StaticMesh.ShowBounds 1
Ovo je korisno da vidite da li bounding box-ovi odgovaraju stvarnoj velicini mesh-eva. Preveliki bounding box-ovi su cest uzrok neefikasnog cullinga.
44.9.5 Vizualizacija Occlusion-a
// Vizualizacija HZB occlusion-a:
r.HZBOcclusion.Visualize 1
// Vizualizacija precomputed visibility celija:
show precomputedvisibility
// (prikazuje grid celija i njihov status)
44.9.6 GPU Visualizer (ProfileGPU)
Za detaljniju analizu GPU performansi, ukljucujuci vreme utroseno na occlusion queries:
// Otvorite GPU profiler:
ProfileGPU
// Ili koristite shortcut: Ctrl+Shift+, (comma)
U GPU profileru mozete videti koliko vremena GPU trosi na:
- HZB Build (izgradnja Hierarchical Z-Buffer-a)
- Occlusion queries
- Nanite culling passes
- Nanite rasterization
44.9.7 Nanite Visualization Modes
Za debugovanje Nanite culling-a, UE5 nudi posebne vizualizacione modove:
- U Viewport-u, kliknite na Lit dropdown
- Izaberite Nanite Visualization
- Birajte izmedju:
- Triangles -- prikazuje gustinu trouglova (pomaze da vidite LOD ponasanje)
- Clusters -- prikazuje individualne klastere razlicitim bojama
- Overdraw -- prikazuje gde se klasteri preklapaju
- Hierarchy -- prikazuje hijerarhiju klastera
- Level of Detail -- prikazuje koji LOD nivo se koristi
Ovi vizualizacioni modovi su neprocenjivi za razumevanje kako Nanite upravlja cullingom i LOD-om u vasoj sceni.
44.9.8 Prakticni debugging workflow
Evo predlozenog workflow-a za debugovanje culling problema:
Korak 1: Identifikujte problem
stat scenerendering
stat initviews
Pogledajte koliko primitiva se renderuje i koliko vremena CPU trosi na culling.
Korak 2: Vizualizujte sta se renderuje
FreezeRendering
Zamrznite renderovanje i obidjite scenu da vidite sta je culled a sta nije.
Korak 3: Proverite bounding box-ove
show bounds
Potrazite prevelike bounding box-ove koji sprecavaju efikasan culling.
Korak 4: Analizirajte Nanite (ako je u upotrebi) Koristite Nanite Visualization modove da vidite koliko klastera se renderuje.
Korak 5: Fino podesite Na osnovu nalaza, podesite cull distances, Cull Distance Volumes, bounding box scale, itd.
44.10 Culling Pipeline -- Kako sve radi zajedno
Do sada smo govorili o individualnim culling tehnikama. Hajde da pogledamo kako one rade zajedno u UE5 rendering pipeline-u.
44.10.1 Redosled operacija
Kada UE5 priprema frame za renderovanje, culling se desava u sledecim fazama:
Svi objekti u sceni
|
v
[1. Distance Culling]
Odbaci objekte koji su predaleko
(na osnovu per-actor cull distance i Cull Distance Volumes)
|
v
[2. Frustum Culling]
Odbaci objekte koji su van view frustuma
(automatski, na osnovu bounding box-a vs. camera frustum)
|
v
[3. Precomputed Visibility]
Odbaci objekte koji su nevidljivi prema baked podacima
(samo za staticke objekte u oblastima sa Precomputed Visibility Volume)
|
v
[4. Software Occlusion / HZB Occlusion]
Odbaci objekte koji su zaklanjeni drugim objektima
(GPU-bazirano za Nanite, CPU ili GPU za ostale)
|
v
Preostali objekti se salju na renderovanje
|
v
[5. Nanite Per-Cluster Culling (za Nanite mesheve)]
Dodatni, finiji culling na nivou klastera
(frustum + occlusion + screen-size, sve na GPU)
|
v
Finalni set geometrije za rasterizaciju
44.10.2 Svaka faza smanjuje posao za sledecu
Primetite da svaka faza smanjuje broj objekata za sledecu fazu. Ovo je vazno jer:
- Distance culling je najjeftiniji test (jedno oduzimanje i poredjenje) i prvi odbacuje daleke objekte
- Frustum culling je sledeei po ceni i odbacuje objekte van vidnog polja
- Precomputed Visibility je skoro besplatna lookup operacija (jedan bit po objektu)
- Occlusion testing je najskuplji test i primenjuje se samo na objekte koji su prosli sve prethodne testove
Ovo je cascading filter pristup -- svaki filter je skuplji ali precizniji, i prima sve manji broj kandidata.
44.10.3 Primer iz prakse
Zamislite open world scenu sa 200.000 objekata:
| Faza | Ulaznih objekata | Culled | Preostalo |
|---|---|---|---|
| Pocetno stanje | 200.000 | - | 200.000 |
| Distance Culling | 200.000 | 140.000 | 60.000 |
| Frustum Culling | 60.000 | 42.000 | 18.000 |
| Precomputed Visibility | 18.000 | 6.000 | 12.000 |
| Occlusion Culling | 12.000 | 4.000 | 8.000 |
| Renderovano | - | - | 8.000 |
Od 200.000 objekata, samo 8.000 se zaista renderuje -- to je 96% redukcija! Bez cullinga, GPU bi morao da obradi geometriju svih 200.000 objekata.
44.11 Napredne teme
44.11.1 Occlusion i Shadows
Jedna cesta greska je zaboraviti da senke imaju sopstveni culling. Svaki shadow-casting light ima svoj frustum (ili vise frustuma za cascaded shadow maps), i objekti se moraju testirati i za renderovanje senki, ne samo za glavnu kameru.
Ovo znaci da objekat koji je culled za glavnu kameru mozda nije culled za shadow map -- njegova senka moze da bude vidljiva cak i kada sam objekat nije. UE5 automatski upravlja ovim, ali je vazno razumeti jer:
- Shadow caster-i imaju drugaciji cull distance od samog mesh-a
- Objekat daleko od kamere moze da baci senku koja je blizu kamere
Cast Shadowproperty na Actor-u kontrolise da li objekat uopste baca senku
// Podesavanje shadow cull distance-a:
// Na Actor-u u Details panelu:
// Shadow Max Draw Distance: 10000 (npr.)
// Ili globalno:
r.Shadow.MaxCSMResolution 2048
r.Shadow.CSM.MaxCascades 4
44.11.2 Occlusion i Transparency
Providni (translucent) objekti predstavljaju poseban izazov za occlusion culling:
- Providni objekat ne moze da bude occluder -- ne zaklanja objekte iza sebe (jer je providan)
- Providni objekat moze da bude occludee -- moze biti zaklonjen neprozirnim objektom
- Ovo znaci da staklo, voda, dim i slicni efekti ne pomazu occlusion culling-u
U praksi, ovo znaci da scene sa mnogo providnih objekata (npr. staklene zgrade) imaju manje koristi od occlusion culling-a.
44.11.3 Culling i Ray Tracing
Hardware ray tracing u UE5 ima sopstvene culling mehanizme koji se razlikuju od rasterizacionog culling-a:
- Ray tracing koristi Bounding Volume Hierarchy (BVH) za brzo pronalazenje preseka zraka sa geometrijom
- BVH je prostorna struktura podataka koja omogucava logaritamsko vreme pretrage
- Objekti koji su culled za rasterizaciju mogu i dalje da budu relevantni za ray tracing (refleksije, globalno osvetljenje, itd.)
Visible in Ray Tracingproperty kontrolise da li je objekat ukljucen u ray tracing BVH
44.11.4 Culling u Multiplayer igrama
U multiplayer igrama (posebno dedicated server), culling ima dodatnu dimenziju:
- Network relevancy -- server koristi slican koncept cullingu da odredi koje objekte da salje kom igracu (NetCullDistanceSquared)
- Server-side culling -- server ne treba da salje informacije o objektima koji su predaleko od igraca
- Ovo nije isto sto i renderovanje culling, ali konceptualno je slicno
// Primer: podesavanje network cull distance na Actor-u
// u konstruktoru Actor-a:
NetCullDistanceSquared = 150000000.0f; // ~12247 UE jedinica
bAlwaysRelevant = false; // Ne salji uvek svim igracima
44.12 Ceste greske i kako ih izbeci
44.12.1 Preveliki mesh-evi
Problem: Jedan mesh pokriva celu zgradu ili ceo nivo terena. Bounding box je ogroman i mesh se gotovo nikada ne culluje.
Resenje: Razbijte mesh na manje delove. Svaka soba, svaki sprat, svaki segment terena treba da bude poseban mesh.
44.12.2 Pogresno postavljeni pivot points
Problem: Mesh ima pivot point daleko od vidljive geometrije (cest problem pri izvozu iz 3D programa). Ovo vestacki povecava bounding box.
Resenje: U 3D programu (Blender, Maya, 3ds Max), resetujte pivot point na centar geometrije pre izvoza.
44.12.3 Nevidljiva geometrija koja povecava bounds
Problem: Mesh ima vertex-e koji su daleko od vidljivog dela -- mozda zaboravljeni vertex-i ili pomocna geometrija koja nije obrisana pre izvoza.
Resenje: Proverite mesh u 3D programu. Selektujte sve vertex-e i proverite da nema usamljenih vertex-a daleko od glavne geometrije.
44.12.4 Previse agresivan cull distance
Problem: Objekti "poppuju" -- iznenada se pojavljuju/nestaju dok se igrac krece.
Resenje:
- Povecajte cull distance za problematicne objekte
- Koristite LOD-ove umesto hard culling-a -- objekat se postepeno uproscava umesto da naglo nestane
- Dodajte dithered fade za postepen prelaz (UE5 podrzava ovo kroz materijal)
// Ukljucivanje dithered LOD tranzicije na mesh-u:
// Static Mesh Editor > LOD Settings:
// LOD Transition: Dithered
// Ovo daje postepen prelaz umesto naglog "poppa"
44.12.5 Zaboravljeni debug vizualizacije
Problem: Ostavili ste show bounds ili vizualizacione modove ukljucene u shipping build-u.
Resenje: Pre finalnog pakovanja, proverite da su svi debug vizualizacioni modovi iskljuceni. UE5 ih automatski iskljucuje u Shipping build-u, ali Development build moze da ih zadrzi.
44.12.6 Neoptimizovani Cull Distance Volumes
Problem: Imate Cull Distance Volume koji pokriva celu mapu sa istim podesavanjima. Razliciti delovi mape imaju razlicite potrebe.
Resenje: Koristite vise Cull Distance Volumes sa razlicitim podesavanjima za razlicite zone. Gusti gradski delovi trebaju agresivniji culling, dok otvoreni tereni trebaju manje agresivan.
44.13 Checklist za optimizaciju culling-a
Evo prakticne checkliste koju mozete pratiti kada optimizujete culling u vasem projektu:
Pre-produkcija:
- Definisati strategiju podele mesh-eva (koliko veliki mogu da budu individualni mesh-evi)
- Definisati kategorije objekata i njihove cull distances (mali, srednji, veliki)
- Odluciti da li cete koristiti Precomputed Visibility (za interior-heavy igre)
- Odluciti da li cete koristiti Nanite (za detaljnu staticku geometriju)
Produkcija:
- Proveravati bounding box-ove mesh-eva pri izvozu iz 3D programa
- Postavljati per-actor cull distance na odgovarajuce vrednosti
- Postavljati Cull Distance Volumes u razlicite zone scene
- Koristiti Nanite za sve kompatibilne staticke mesh-eve
- Pravilno postavljati pivot points
QA / Optimizacija:
- Koristiti
stat scenerenderingda proverite koliko se renderuje - Koristiti
stat initviewsda proverite koliko CPU trosi na culling - Koristiti
FreezeRenderingda vizualizujete culling - Koristiti
show boundsda proverite bounding box-ove - Proveriti da li ima poppinga (preterano agresivan culling)
- Proveriti da li ima nepotrebnog renderovanja (nedovoljno agresivan culling)
- Profilisati GPU sa
ProfileGPUza occlusion overhead - Testirati na target hardveru (ne samo na development masini)
44.14 Konzolne komande -- Sveobuhvatna referenca
Ovde su sve relevantne konzolne komande za rad sa culling-om u UE5, organizovane po kategorijama:
Frustum Culling:
// Frustum culling je uvek ukljucen i ne moze se iskljuciti
// Ali mozete videti njegove efekte:
FreezeRendering // Toggle zamrzavanja renderovanja
stat initviews // Prikaz vremena za visibility testove
Distance Culling:
r.ViewDistanceScale 1.0 // Globalni skaler za sve cull distances
// 0.5 = upola kraci cull distance
// 2.0 = duplo duzi cull distance
// Korisno za scalability settings
foliage.CullDistanceScale 1.0 // Poseban skaler za foliage
Precomputed Visibility:
show precomputedvisibility // Vizualizacija celija
r.PrecomputedVisibilityWarning 1 // Upozorenja za probleme
Occlusion Culling:
r.HZBOcclusion 1 // Hierarchical Z-Buffer occlusion (on/off)
r.AllowOcclusionQueries 1 // Hardware occlusion queries (on/off)
r.SO.Enable 1 // Software Occlusion (on/off)
r.SO.BufferSize 256 // Software Occlusion buffer velicina
Nanite:
r.Nanite.MaxPixelsPerEdge 1.0 // LOD agresivnost
stat Nanite // Nanite statistike
r.Nanite.Visualize.Overview 1 // Nanite vizualizacija
Debugging:
FreezeRendering // Zamrzni/odmrzni renderovanje
show bounds // Prikazi bounding box-ove
stat scenerendering // Rendering statistike
stat initviews // Visibility statistike
ProfileGPU // GPU profiler
r.VisualizeOccludedPrimitives 1 // Vizualizacija occluded objekata
Scalability (kvalitet vs. performanse):
sg.ViewDistanceQuality 3 // 0=Low, 1=Medium, 2=High, 3=Epic, 4=Cinematic
sg.FoliageQuality 3 // Isto za foliage
44.15 Odnos sa World Partition sistemom
Kao sto smo pomenuli ranije (i detaljno objasnili u Poglavlju 32), World Partition i culling su komplementarni sistemi:
| Aspekt | World Partition | Culling |
|---|---|---|
| Sta radi | Kontrolise koji delovi sveta su ucitani u memoriju | Kontrolise koji ucitani objekti se renderuju |
| Granularnost | Grid celije (stotine/hiljade metara) | Individualni objekti/klasteri |
| Uticaj na memoriju | Da -- ne ucitava objekte u RAM | Ne -- objekti ostaju u memoriji |
| Uticaj na renderovanje | Indirektno (manje ucitanih = manje za render) | Direktno (eksplicitno skipuje renderovanje) |
| Latencija promene | Visoka (streaming zahteva vreme) | Niska (per-frame odluka) |
Kako rade zajedno:
- World Partition odredjuje koji "komadi" sveta su ucitani (bazirano na streaming distance)
- Od ucitanih objekata, culling odredjuje koji se renderuju (bazirano na frustum, distance, occlusion)
- Streaming distance treba da bude veci od cull distance-a da bi objekti bili spremni pre nego sto postanu vidljivi
// Primer:
// World Partition streaming distance: 100.000 (1km)
// Cull Distance Volume max draw distance za taj tip: 70.000 (700m)
//
// Objekat na 800m udaljenosti:
// - Ucitan u memoriju (800m < 1000m streaming distance) ✓
// - Ali nije renderovan (800m > 700m cull distance) ✓
//
// Kada igrac pridje na 600m:
// - Objekat je vec u memoriji (nema streaming delay-a)
// - Sada se renderuje (600m < 700m cull distance) ✓
44.16 Culling u kontekstu celokupnog rendering pipeline-a
Da biste u potpunosti razumeli gde culling "zivi" u rendering pipeline-u, evo siroke slike:
[Game Thread]
|
+-- Tick svih Actor-a
+-- Animacije, fizika, AI
+-- Priprema scene za renderovanje
|
[Render Thread]
|
+-- [CULLING FAZA]
| +-- Distance Culling
| +-- Frustum Culling
| +-- Precomputed Visibility
| +-- Occlusion Query rezultati (iz prethodnog frame-a)
| +-- Kreiranje liste vidljivih objekata
|
+-- [SETUP FAZA]
| +-- Sortiranje objekata po materijalu
| +-- Priprema draw call-ova
| +-- Dynamic instancing/batching
|
+-- [SLANJE GPU-U]
| +-- Command buffer submission
|
[GPU]
|
+-- [DEPTH PRE-PASS]
| +-- Renderuj dubinu svih neprozirnih objekata
| +-- Generisi HZB za occlusion
|
+-- [NANITE CULLING] (za Nanite mesheve)
| +-- Instance culling
| +-- Per-cluster frustum + occlusion culling (Two-pass)
| +-- Nanite rasterization
|
+-- [BASE PASS]
| +-- Renderuj boje, normale, materijale
|
+-- [LIGHTING]
| +-- Shadow maps (sa sopstvenim cullingom!)
| +-- Deferred lighting
|
+-- [POST-PROCESSING]
| +-- Bloom, tone mapping, anti-aliasing, itd.
|
+-- [OCCLUSION QUERIES]
+-- Posalji query-je za sledeci frame
Kao sto vidite, culling se desava rano u pipeline-u (i na CPU i na GPU) i direktno utice na kolicinu posla koji ostatak pipeline-a mora da obavi.
44.17 Performansne implikacije -- Brojevi iz prakse
Da bismo ilustrovali koliko culling zaista znaci, evo nekih tipicnih brojeva (napomena: ovi brojevi su okvirni i zavise od konkretne scene i hardvera):
CPU uticaj:
| Metrika | Bez cullinga | Sa cullingom | Usteda |
|---|---|---|---|
| Draw calls po frame-u | 15.000 | 3.000 | 80% |
| CPU render thread vreme | 22ms | 6ms | 73% |
| Visibility determination | 0ms | 0.5ms | Cost cullinga |
Da, culling sam po sebi ima cost (0.5ms u ovom primeru), ali ustedevi su ogromne (16ms manje na render thread-u).
GPU uticaj:
| Metrika | Bez cullinga | Sa cullingom | Usteda |
|---|---|---|---|
| Trouglova po frame-u | 50M | 8M | 84% |
| Vertex shader vreme | 4ms | 0.8ms | 80% |
| Rasterization vreme | 6ms | 1.5ms | 75% |
| Pixel shader vreme | 12ms | 4ms | 67% |
| Ukupno GPU frame time | 22ms | 6.3ms | 71% |
Nanite dodatan uticaj:
| Metrika | Tradicionalni culling | Nanite culling | Usteda |
|---|---|---|---|
| Vidljivi trouglovi | 8M | 3M | 62.5% |
| Nanite culling cost | - | 0.3ms | Cost Nanite cullinga |
Nanite dodatno smanjuje broj trouglova jer radi per-cluster culling i automatski LOD, sto tradicionalni culling ne moze da postigne na tom nivou granulariteta.
44.18 Cross-reference sa drugim poglavljima
Culling je tema koja se prepice sa mnogim drugim temama u ovoj knjizi:
-
Poglavlje 03 -- Bounding Volumes (AABB, Sphere, OBB): Razumevanje bounding volumena je fundamentalno za razumevanje cullinga. Svaki culling test koristi bounding volume objekta.
-
Poglavlje 06 -- View Frustum i projekcija: Frustum culling se direktno oslanja na razumevanje view frustuma. Znanje o near/far plane-u, field of view i aspect ratio-u pomaze u razumevanju zasto se odredjeni objekti culluju a drugi ne.
-
Poglavlje 30 -- Nanite geometrija: Nanite culling je detaljnije obradjen u Poglavlju 30, sa fokusom na internu arhitekturu klasterizacije. Ovde smo se fokusirali na culling aspekt Nanite-a u kontekstu sireg culling sistema.
-
Poglavlje 32 -- World Partition i streaming: World Partition kontrolise ucitavanje, a culling kontrolise renderovanje. Ova dva sistema moraju da rade u harmoniji za optimalne performanse u open world scenama.
44.19 Tabela kljucnih pojmova
| Termin | Objasnjenje |
|---|---|
| Culling | Proces odbacivanja objekata koji ne treba da se renderuju, radi ustede CPU i GPU resursa. |
| Frustum Culling | Odbacivanje objekata koji su van vidnog polja kamere (view frustum). Automatski u UE5. |
| Distance Culling | Odbacivanje objekata koji su dalje od definisane maksimalne udaljenosti od kamere. |
| Cull Distance Volume | UE5 Volume actor koji definise pravila za distance culling na osnovu velicine objekata. |
| Occlusion Culling | Odbacivanje objekata koji su zaklanjeni (occluded) drugim objektima i stoga nevidljivi. |
| Occluder | Objekat koji zaklanja druge objekte (npr. zid). |
| Occludee | Objekat koji je potencijalno zaklonjen od strane occluder-a. |
| Precomputed Visibility | Offline izracunata vidljivost za staticne scene, cuvana kao bitmaska po celiji prostora. |
| Software Occlusion Culling | CPU-bazirano occlusion testiranje koristeci pojednostavljen depth buffer. |
| Hardware Occlusion Queries | GPU upiti koji testiraju da li bi bounding box objekta bio vidljiv na ekranu. |
| HZB (Hierarchical Z-Buffer) | Hijerarhijska verzija depth buffer-a (mipmap lanac), koriscena za efikasno occlusion testiranje. |
| Nanite Cluster Culling | Per-cluster GPU-driven culling specifican za Nanite mesh-eve, sa two-pass pristupom. |
| Bounding Box (AABB) | Axis-Aligned Bounding Box -- najmanji pravougaonik poravnat sa koordinatnim osama koji obuhvata ceo mesh. Koristi se za brze culling testove. |
| Bounding Sphere | Najmanji krug (sfera) koji obuhvata ceo mesh. Alternativa AABB-u za culling testove. |
| Draw Call | Komanda CPU-a GPU-u da renderuje odredjenu geometriju sa odredjenim materijalima. Svaki draw call ima overhead. |
| Overdraw | Situacija gde se isti piksel na ekranu renderuje vise puta jer se objekti preklapaju u dubini. |
| View Frustum | Zarubljena piramida koja opisuje vidno polje kamere, definisana sa 6 ravni. |
| PVS (Potentially Visible Set) | Skup objekata koji su potencijalno vidljivi iz odredjene tacke ili oblasti u prostoru. |
| FreezeRendering | UE5 komanda koja zamrzava renderovanje na trenutnoj poziciji kamere, omogucavajuci kretanje po sceni radi debugovanja. |
| LOD (Level of Detail) | Tehnika koriscenja pojednostavljenih verzija mesh-eva na vecim udaljenostima od kamere. |
| HLOD (Hierarchical LOD) | Tehnika gde se grupa objekata na velikoj udaljenosti zamenjuje jednim pojednostavljenim mesh-om. |
| Two-Pass Occlusion | Nanite-ov pristup gde se u prvom prolazu koristi HZB iz prethodnog frame-a, a u drugom prolazu se koristi HZB generisan u prvom prolazu, cime se eliminise latencija. |
| Screen-Size Culling | Odbacivanje objekata/klastera koji zauzimaju premalo piksela na ekranu da bi bili vizuelno znacajni. |
| World Partition | UE5 sistem za streaming delova otvorenog sveta, komplementaran sa cullingom. |
44.20 Korisni linkovi i dodatno citanje
Zvanicna Unreal Engine dokumentacija:
-
Visibility and Occlusion Culling Overview: https://dev.epicgames.com/documentation/en-us/unreal-engine/visibility-and-occlusion-culling-in-unreal-engine
-
Cull Distance Volume: https://dev.epicgames.com/documentation/en-us/unreal-engine/cull-distance-volume
-
Precomputed Visibility: https://dev.epicgames.com/documentation/en-us/unreal-engine/precomputed-visibility-volumes-in-unreal-engine
-
Nanite Virtualized Geometry: https://dev.epicgames.com/documentation/en-us/unreal-engine/nanite-virtualized-geometry-in-unreal-engine
-
World Partition: https://dev.epicgames.com/documentation/en-us/unreal-engine/world-partition-in-unreal-engine
Tehnicke prezentacije i blogovi:
-
"Nanite -- A Deep Dive" (Brian Karis, SIGGRAPH 2021): Detaljna prezentacija o Nanite arhitekturi ukljucujuci culling pipeline.
-
"Large Worlds in UE5" (Epic Games, GDC): Prezentacija o tehnikama za upravljanje velikim svetovima u UE5.
-
"GPU-Driven Rendering Pipelines" (Wihlidal, SIGGRAPH 2015): Fundamentalna prezentacija o GPU-driven renderingu koji je osnova za Nanite culling.
Korisni YouTube kanali:
- Unreal Engine official channel -- tutoriali o optimizaciji
- William Faucher -- napredni UE5 tutoriali
- Ben Cloward -- tehnicke teme o renderovanju
Rezime poglavlja
U ovom poglavlju smo prosli kroz kompletan culling sistem u Unreal Engine 5:
-
Frustum Culling je automatski i besplatan -- odbacuje sve sto je van vidnog polja kamere. Kljuc efikasnosti je pravilna velicina bounding box-ova.
-
Distance Culling je jednostavan ali mocan alat -- preko per-actor settings-a i Cull Distance Volumes mozete fino kontrolisati na kojoj udaljenosti objekti nestaju.
-
Precomputed Visibility je idealan za interior scene sa mnogo occlusion-a -- offline build izracunava vidljivost i runtime lookup je skoro besplatan.
-
Software Occlusion Culling radi na CPU bez latencije, ali je ogranicen u preciznosti i skalabilnosti.
-
Hardware Occlusion Queries su precizne ali imaju problem latencije od 1-2 frame-a. HZB (Hierarchical Z-Buffer) je napredna varijanta koju UE5 preferira.
-
Nanite Per-Cluster Culling je revolucija -- GPU-driven, per-cluster granularitet, two-pass pristup bez latencije. Radi samo za Nanite-enabled mesh-eve.
-
Sve ove tehnike rade zajedno kao kaskadni filteri -- svaka faza smanjuje posao za sledecu.
-
Za debugovanje koristite
FreezeRendering,show bounds,stat scenerendering,stat initviewsi Nanite vizualizacione modove.
Culling nije glamurozna tema -- nema vizuelno impresivnih rezultata kao post-processing efekti ili napredni materijali. Ali bez pravilnog culling-a, nijedna od tih glamuroznih stvari ne bi bila moguca pri prihvatljivom frame rate-u. Culling je temelj na kome se gradi svaka performantna igra, i razumevanje ovih tehnika ce vam pomoci da pravite scene koje izgledaju sjajno i rade glatko.
U sledecem poglavlju, nastavicemo sa optimizacijom i pogledacemo kako profilisati i optimizovati shader kompleksnost i GPU workload.
Kraj Poglavlja 44