Poglavlje 31: Virtual Shadow Maps (VSM)
"Senke su ono sto scenu cini stvarnom -- ali su oduvek bile i najskuplji deo renderovanja. Virtual Shadow Maps su Epicov odgovor na pitanje: kako napraviti senke dostojne Nanite geometrije?"
Uvod
Dobrodosli u jedno od najvaznijih poglavlja ove knjige. Ako ste pratili nas put od samog pocetka, prosli ste kroz osnove renderovanja (Poglavlje 9 -- depth buffer), naucili kako funkcionisu klasicne senke (Poglavlje 13 -- shadow mapping teorija), i upravo ste se upoznali sa revolucionarnim Nanite sistemom (Poglavlje 30). Sada je vreme da spojimo sve te kockice i upoznamo se sa Virtual Shadow Maps -- sistemom senki koji je dizajniran od nule da radi ruku pod ruku sa Nanite geometrijom.
Virtual Shadow Maps (u daljem tekstu: VSM) nisu samo poboljsanje starog sistema. Ovo je potpuno nova arhitektura za renderovanje senki u Unreal Engine 5, koja menja fundamentalni pristup problemu. Umesto da se pitamo "koliko rezolucije mozemo priustiti?", VSM postavlja pitanje: "sta ako shadow map bude tako velik da nikad ne ponestane rezolucije -- ali renderujemo samo ono sto zaista treba?"
U ovom poglavlju cemo detaljno proci kroz:
- Zasto su stari sistemi (pre svega Cascaded Shadow Maps) postali nedovoljni
- Kako VSM radi iznutra -- od virtualnih stranica do fizickog memorijskog pool-a
- Kako se kesiranje koristi da se drasticno smanji cena renderovanja senki
- Kako Nanite i VSM saradjuju kao idealni partneri
- Kako se VSM ponasa sa razlicitim tipovima svetla
- Koja podesavanja su vam na raspolaganju i kako ih koristiti
- Najcesce probleme i kako ih resiti
Krenimo!
31.1 Zasto VSM postoji -- ogranicenja klasicnih sistema
31.1.1 Kratka rekapitulacija: kako rade klasicne senke
Kao sto smo detaljno objasnili u Poglavlju 13, shadow mapping u svojoj osnovi radi ovako: renderujemo scenu iz perspektive svetla u poseban depth buffer (shadow map), a zatim prilikom renderovanja iz perspektive kamere proveravamo da li je svaki piksel "vidljiv" iz svetla ili ne. Ako nije vidljiv -- u senci je.
Cascaded Shadow Maps (CSM) su dugo bili standard za direkcionalna svetla (tipicno sunce). CSM deli frustum kamere na nekoliko "kaskada" (obicno 3-5), gde svaka kaskada pokriva sve vecu oblast scene, ali sa sve manjom rezolucijom shadow map-a. Blize kaskade imaju visu rezoluciju (jer su blize kameri i vidljivije), dok dalje kaskade pokrivaju ogroman prostor ali sa grubom rezolucijom.
Ovaj pristup je funkcionisao odlicno -- sve do pojave Nanite-a.
31.1.2 Problem: Nanite geometrija protiv CSM rezolucije
Zamislite sledecu situaciju. Imate arhitektonsku scenu sa milionima poligona -- detaljne fasade zgrada, ornamenti, reljefne povrsine, vegetacija. Nanite sve to renderuje besprekorno, sa pixel-perfect detaljima. Svaki mali ornament, svaki list, svaka ciglica -- sve je tu, ostro i precizno.
A onda pogledate senke tih istih objekata.
Sa klasicnim CSM-om, shadow map ima fiksnu rezoluciju -- recimo 2048x2048 piksela po kaskadi. Ta rezolucija mora da pokrije ogromnu oblast scene. Rezultat? Senke su:
- Aliased (nazubljene) -- fini detalji geometrije se ne vide u senkama jer shadow map jednostavno nema dovoljno rezolucije da ih uhvati
- Blocky (pikselaste) -- ivice senki su grube i stepenaste, posebno na srednjim i velikim rastojanjima
- Nekonzistentne sa geometrijom -- vidite savrseno ostru geometriju, ali njene senke izgledaju kao da pripadaju potpuno drugoj sceni
Ovo je fundamentalni problem: Nanite je dramaticno podigao kvalitet geometrije, ali senke nisu mogle da prate. Razlika u kvalitetu je postala toliko ocigledna da je kvarila celokupni vizuelni utisak.
31.1.3 Matematika problema
Hajde da stavimo brojke na sto. Tipicna CSM konfiguracija za sunce:
| Kaskada | Oblast (priblizno) | Shadow Map rezolucija | Efektivna gustina |
|---|---|---|---|
| 0 (blizu) | 10m x 10m | 2048 x 2048 | ~205 teksela/m |
| 1 | 40m x 40m | 2048 x 2048 | ~51 teksela/m |
| 2 | 160m x 160m | 2048 x 2048 | ~13 teksela/m |
| 3 (daleko) | 640m x 640m | 2048 x 2048 | ~3 teksela/m |
Na rastojanju od 100 metara, imate otprilike 13 teksela po metru za senke. To znaci da detalji manji od ~7.7 centimetara jednostavno nestaju iz senki. A Nanite vam upravo renderuje geometriju sa detaljima reda velicine milimetra!
Mozete povecati rezoluciju shadow map-a, ali to brzo postaje neodrzivo:
- 4096x4096 udvostrucuje memoriju i rendering cost
- 8192x8192 dodatno cetvorostruko
- A i dalje niste ni blizu Nanite nivoa detalja
31.1.4 Dodatni problemi CSM-a
Osim ciste rezolucije, CSM ima i druge probleme koji postaju izrazeniji sa Nanite geometrijom:
-
Shadow acne i Peter Panning -- bias podesavanja koja su neophodna kod CSM-a cesto dovode do vidljivih artifakata, posebno na finoj geometriji
-
Kaskadni prelazi -- prelaz izmedju kaskada moze biti vidljiv kao nagli pad kvaliteta senki; blending izmedju kaskada kosta dodatne performance
-
Ogranicen domet -- CSM tipicno pokriva samo nekoliko stotina metara; dalje od toga, senke jednostavno ne postoje ili se koriste alternative poput distance field shadows
-
Sve-ili-nista rendering -- svaki frejm, ceo shadow map se renderuje iznova, cak i ako se nista u sceni nije promenilo; ovo je ogroman gubitak za staticne scene
-
Point i Spot svetla -- CSM je dizajniran za direkcionalna svetla; point i spot svetla koriste zasebne sisteme sa sopstvenim ogranicenjima i nedoslednostima
31.1.5 Potreba za novim pristupom
Iz svih ovih razloga, Epic Games je dosao do zakljucka da poboljsavanje CSM-a nije dovoljno. Potreban je potpuno novi sistem senki koji:
- Moze da ponudi konzistentno visoku rezoluciju na svim rastojanjima
- Efikasno koristi memoriju -- ne alocira resurse za oblasti koje nisu vidljive
- Kesira rezultate -- ne renderuje sve iznova svaki frejm
- Nativno radi sa Nanite-om -- koristi prednosti Nanite-ove cluster-based arhitekture
- Unificirano radi sa svim tipovima svetla -- direkcionalna, point, spot
Taj sistem je Virtual Shadow Maps.
31.2 Kako VSM radi -- arhitektura sistema
31.2.1 Osnovna ideja: virtuelna memorija za senke
Ako ste ikada ucili o operativnim sistemima, verovatno ste se sreli sa konceptom virtual memory. Operativni sistem daje svakom procesu iluziju da ima ogroman, kontinualan adresni prostor, ali u stvarnosti samo delovi tog prostora su zaista mapirani na fizicku memoriju (RAM). Stranice (pages) koje nisu trenutno potrebne ne zauzimaju fizicku memoriju.
VSM primenjuje identican princip na shadow maps:
- Shadow map je "virtuelno" ogroman -- zamislite shadow map rezolucije 16384 x 16384 ili cak veci
- Ovaj ogroman shadow map je podeljen na male stranice (pages) od 128 x 128 teksela svaka
- Samo stranice koje su zaista potrebne (vidljive iz kamere i relevantne za senke) su alocirane u fizickoj memoriji
- Ostatak postoji samo kao "virtuelni" prostor -- ne zauzima memoriju i ne kosta nista za renderovanje
Ovo je ista ideja kao Virtual Textures (ako ste upoznati sa tim sistemom), samo primenjena na shadow maps umesto na albedo/normal teksture.
31.2.2 Struktura: Virtual Page, Physical Page, Page Table
Hajde da razbijemo arhitekturu na njene komponente:
Virtual Pages (Virtuelne stranice)
Ceo shadow map za jedno svetlo je podeljen u mrezu virtuelnih stranica. Svaka stranica je 128 x 128 teksela. Za shadow map od 16384 x 16384, to je 128 x 128 = 16.384 virtuelnih stranica.
Ali -- i ovo je kljucna stvar -- vecina ovih stranica nikada nece biti potrebna. Mozda je samo 500-2000 stranica zaista relevantno u bilo kom trenutku.
Physical Page Pool (Fizicki bazen stranica)
U GPU memoriji postoji fiksno alociran page pool -- bazen fizickih stranica. Ovo je stvarna memorija koja cuva rendered shadow podatke. Velicina page pool-a je konfigurisana (tipicno 2-4 GB) i predstavlja gornju granicu koliko shadow podataka moze biti aktivno u isto vreme.
Page pool je organizovan kao 2D atlas tekstura -- velika tekstura u koju se shadow stranice pakuju jedna do druge.
+---+---+---+---+---+---+---+---+
| P0| P1| P2| P3| P4| P5| P6| P7| <- Fizicki Page Pool (atlas)
+---+---+---+---+---+---+---+---+
| P8| P9|P10|P11|P12|P13|P14|P15|
+---+---+---+---+---+---+---+---+
|P16|P17| | | | | | | <- Prazna mesta za nove stranice
+---+---+---+---+---+---+---+---+
Svako "P" polje je jedna fizicka stranica od 128 x 128 teksela.
Page Table (Tabela stranica)
Izmedju virtuelnih i fizickih stranica stoji page table -- indirekciona tabela koja mapira virtuelne stranice na fizicke lokacije u page pool-u. Ovo je direktna analogija sa page table-om u virtualnoj memoriji operativnog sistema.
Virtual Shadow Map (ogroman, ali vecinom prazan):
+----+----+----+----+----+----+----+----+
| | | | V3 | | | | |
+----+----+----+----+----+----+----+----+
| | V1 | | | | | | |
+----+----+----+----+----+----+----+----+
| | | | | | V5 | | | Page Table:
+----+----+----+----+----+----+----+----+ V1 -> P2
| | | V2 | | | | | | V2 -> P0
+----+----+----+----+----+----+----+----+ V3 -> P5
| | | | | V4 | | | | V4 -> P1
+----+----+----+----+----+----+----+----+ V5 -> P3
(ostale -> NOT MAPPED)
Kada shader treba da procita shadow vrednost na odredjenoj poziciji:
- Izracuna koja virtuelna stranica pokriva tu poziciju
- Pogleda u page table da li je ta stranica mapirana
- Ako jeste -- procita shadow podatak iz odgovarajuce fizicke stranice
- Ako nije -- ta oblast nema renderovanu senku (fallback ponasanje)
31.2.3 Clipmap pristup za direkcionalna svetla
Za direkcionalna svetla (pre svega sunce), VSM koristi clipmap strukturu. Clipmap je hijerarhija nivoa sa razlicitim rezolucijama, centriranih oko kamere -- koncept poznat iz terena (geometry clipmaps) i tekstura.
Zamislite sledece: oko kamere postoji niz koncentricnih kvadrata, gde svaki sledeci pokriva duplo vecu oblast ali sa duplo manjom rezolucijom:
Clipmap nivoi (pogled odozgo, kamera u centru):
+---------------------------+
| Nivo 3 (najsiri, |
| najmanja rezolucija) |
| +-------------------+ |
| | Nivo 2 | |
| | +-----------+ | |
| | | Nivo 1 | | |
| | | +-----+ | | |
| | | |N0 | | | |
| | | |(cam)| | | |
| | | +-----+ | | |
| | +-----------+ | |
| +-------------------+ |
+---------------------------+
Svaki nivo clipmap-a je sam za sebe virtuelni shadow map sa sopstvenim stranicama. Prednost u odnosu na CSM:
- Nema kaskadnih prelaza -- nivoi se glatko nadovezuju
- Svaki nivo je virtualan -- alociraju se samo stranice koje pokrivaju stvarnu geometriju
- Rezolucija ostaje konzistentna u okviru svakog nivoa
Kljucna razlika u odnosu na CSM: dok CSM svaki frejm renderuje ceo shadow map za svaku kaskadu, clipmap u VSM-u renderuje samo stranice koje se promenile ili koje su nove (jer se kamera pomerila ili jer se geometrija promenila).
31.2.4 Odredjivanje potrebnih stranica
Kako VSM zna koje stranice treba alocirati i renderovati? Proces ide ovako:
Korak 1: Analiza vidljivosti (Feedback pass)
Tokom renderovanja glavne scene, za svaki piksel se odredjuje:
- Koja svetla uticu na taj piksel
- Koja virtuelna stranica shadow map-a bi se koristila za to svetlo na toj poziciji
Ovi podaci se zapisuju u feedback buffer -- listu potrebnih stranica.
Korak 2: Analiza potrebnih stranica
Engine prolazi kroz feedback buffer i pravi listu svih potrebnih virtuelnih stranica koje trenutno nisu mapirane ili kojima je istekao kes.
Korak 3: Alokacija fizickih stranica
Za svaku potrebnu virtuelnu stranicu, alocira se fizicka stranica iz page pool-a. Ako je pool pun, koristi se LRU (Least Recently Used) politika eviction-a -- najstarije nekoriscene stranice se oslobadjaju.
Korak 4: Rendering
Samo novo-alocirane ili invalidated stranice se renderuju. Svaka stranica se renderuje nezavisno -- sto znaci da Nanite moze da renderuje samo klastere geometrije koji su relevantni za tu konkretnu stranicu.
31.2.5 Detaljniji pogled na page indirection
Da bismo bolje razumeli kako shader pristupa shadow podacima, hajde da pratimo ceo tok za jedan piksel:
1. Fragment shader izracunava world position piksela
2. Transformise world position u shadow map prostor (light space)
3. Iz light space koordinata izracunava:
a) Koji clipmap nivo (za direkcionalna svetla)
b) Koju virtuelnu stranicu unutar tog nivoa
c) Lokalni offset unutar te stranice (0-127, 0-127)
4. Cita page table za taj (nivo, stranica) par
5. Page table vraca:
a) Fizicku lokaciju stranice u page pool-u (ako je mapirana)
b) "Not mapped" flag (ako stranica nije alocirana)
6. Ako je mapirana: cita depth vrednost iz page pool-a
na poziciji (fizicka_lokacija + lokalni_offset)
7. Poredi sa depth piksela da odredi da li je u senci
Ovaj proces indirekcije (virtual -> physical) dodaje jedan ekstra korak citanja teksture u odnosu na klasican shadow map, ali taj trosak je minimalan u poredjenju sa dobitima.
31.2.6 Rezolucija i preciznost
VSM koristi 16-bit depth format za shadow stranice (R16_UNORM ili slicno), sto daje dovoljnu preciznost za vecinu scenarija. U poredjenju:
- Klasican shadow map obicno koristi 24-bit ili 32-bit depth
- VSM kompenzuje nizu bit-depth vecom efektivnom rezolucijom (jer svaka stranica pokriva manju oblast scene)
Efektivna rezolucija VSM-a u blizini kamere moze biti ekvivalentna shadow map-u od 32768 x 32768 ili vise, sto je daleko iznad onoga sto bi bilo prakticno sa klasicnim pristupom.
31.3 Kesiranje i invalidacija -- srce performansi
31.3.1 Zasto je kesiranje kljucno
Zamislite da imate scenu sa 2000 aktivnih shadow stranica. Ako biste svaku stranicu renderovali svaki frejm, to bi bilo:
- 2000 render pass-ova
- Svaki sa potencijalno milionima trouglova (Nanite geometrija)
- Na 60 FPS, to je 120.000 render pass-ova u sekundi
Ovo bi bilo katastrofalno za performanse. Ali -- i ovo je genijalnost VSM sistema -- vecina scene se ne menja izmedju frejmova.
Zgrada stoji na mestu. Teren se ne pomera. Drvo ne raste u realnom vremenu (obicno). Stene, zidovi, podovi, plafoni -- sva ta staticna geometrija baca potpuno iste senke frejm za frejmom.
VSM iskoriscava ovu cinjenicu agresivnim kesiranjem: jednom renderovana stranica ostaje validna sve dok se nista ne promeni.
31.3.2 Kako kesiranje funkcionise
Svaka fizicka stranica u page pool-u ima pridruzen status:
enum PageStatus {
EMPTY, // Stranica nije renderovana
VALID, // Renderovana i azurna -- moze se koristiti
INVALIDATED, // Nesto se promenilo, treba ponovo renderovati
EVICTED // Izbacena iz pool-a (LRU), treba ponovo alocirati
};
Tok rada izgleda ovako:
Frejm 1 (prvi frejm, prazan kes):
- Analizira se scena -- potrebno je 1500 stranica
- Sve stranice su EMPTY -- sve moraju biti renderovane
- Renderuje se svih 1500 stranica
- Sve dobijaju status VALID
- Ovo je najskuplji frejm -- o cemu cemo detaljnije pricati kasnije
Frejm 2 (nista se nije promenilo):
- Analizira se scena -- i dalje je potrebno 1500 stranica
- Sve stranice su VALID -- nista ne treba renderovati!
- Cena renderovanja senki je prakticno nula
- Samo se koriste kesirani podaci iz page pool-a
Frejm 3 (kamera se pomerila malo unapred):
- Neke nove oblasti su sada vidljive, neke stare nisu
- Mozda 50 novih stranica treba alocirati i renderovati
- Mozda 40 starih stranica vise nije potrebno (oslobadjaju se ili ostaju u kesu za slucaj da se kamera vrati)
- Renderuje se samo 50 novih stranica -- mnogo jeftinije od 1500!
Frejm 4 (igrac otvorio vrata -- dinamican objekat se pomerio):
- Stranice koje pokrivaju oblast oko vrata se invalidiraju
- Mozda 10-20 stranica treba ponovo renderovati
- Ostalih 1480+ stranica ostaje VALID
31.3.3 Staticka vs. dinamicka geometrija
VSM pravi krucijalnu razliku izmedju staticke i dinamicke geometrije:
Staticka geometrija
Sva geometrija koja je oznacena kao Static ili Stationary u editoru (sto ukljucuje vecinu okruzenja -- zgrade, teren, stene, namestaj koji se ne pomera):
- Renderuje se u shadow stranicu jednom
- Kesira se neograniceno -- sve dok ta stranica ostaje u page pool-u
- Invalidira se samo ako se svetlo pomeri (npr. promena ugla sunca tokom dan-noc ciklusa)
Ovo je ogroman dobitak za performanse. U tipicnoj sceni, 90-99% geometrije je staticna, sto znaci da je 90-99% shadow stranica kesirano nakon prvog renderovanja.
Dinamicka geometrija
Sva geometrija koja se pomera (likovi, vozila, fizicki objekti, animirani elementi):
- Shadow stranice koje pokrivaju dinamicke objekte se invalidiraju svaki frejm
- Te stranice moraju biti ponovo renderovane svaki frejm
- ALI -- renderuje se samo geometrija unutar te stranice, ne cela scena
Vazna optimizacija: VSM moze da razdvoji staticku i dinamicku geometriju unutar iste stranice. Staticka geometrija ostaje kesirana, a samo dinamicka geometrija se ponovo renderuje i "composit-uje" preko staticnog sloja. Ovo se ponekad naziva "separate static/dynamic caching" i drasticno smanjuje cenu dinamickih objekata.
31.3.4 Cache hit rate -- kljucna metrika
Cache hit rate je procenat shadow stranica koje su uspesno procitane iz kesa bez potrebe za ponovnim renderovanjem. Ovo je najvaznija metrika za performanse VSM-a:
| Cache Hit Rate | Tipican scenario | Performanse |
|---|---|---|
| 95-100% | Staticna scena, kamera se ne pomera | Odlicne -- minimalan trosak senki |
| 85-95% | Normalno kretanje kamere kroz staticnu scenu | Vrlo dobre |
| 70-85% | Aktivna scena sa umerenim brojem dinamickih objekata | Dobre |
| 50-70% | Mnogo dinamickih objekata ili brzo kretanje kamere | Prihvatljive, ali primetno |
| < 50% | Dan-noc ciklus, mnogo pokretne geometrije | Potencijalno problematicno |
Mozete pratiti cache hit rate u UE5 pomocu konzolne komande:
stat ShadowRendering
ili detaljnije:
r.Shadow.Virtual.ShowStats 1
31.3.5 Invalidacioni mehanizmi
Stranica se invalidira (gubi VALID status) u sledecim situacijama:
- Geometrija udje u oblast stranice -- novi objekat baca senku koja pada na tu stranicu
- Geometrija izadje iz oblasti stranice -- objekat koji je bacao senku se pomerio
- Geometrija se promeni -- animacija, deformacija, promena materijala koji utice na opacity
- Svetlo se pomeri -- promena pozicije, rotacije ili parametara svetla
- Svetlo promeni intenzitet ili boju -- u nekim slucajevima zahteva re-render (zavisi od implementacije)
- Clipmap se pomeri -- kamera se pomerila dovoljno da clipmap nivo mora biti azuriran
- Forsirano -- igra eksplicitno zahteva invalidaciju (npr. posle level streaming-a)
Engine interno prati bounding box svakog objekta i efikasno odredjuje koje stranice su pogodjene promenom. Ovo se radi kroz prostornu strukturu podataka (obicno grid ili quadtree) koja omogucava brzo pretraga tipa "koji objekti se preklapaju sa ovom stranicom".
31.3.6 Invalidation distance
Postoji podesavanje koje kontrolise na kom rastojanju od kamere se dinamicka geometrija uzima u obzir za invalidaciju senki:
r.Shadow.Virtual.InvalidationDistance
Objekti dalje od ove udaljenosti nece invalidirati shadow stranice cak i ako se pomeraju. Ovo je vazna optimizacija -- lik koji trci na rastojanju od 500 metara nema smisla da invalidira stranice koje kamera jedva vidi.
Tipicna vrednost je 2000-5000 unreal units (20-50 metara), ali zavisi od vase scene i potreba.
31.4 Integracija sa Nanite
31.4.1 Zasto su Nanite i VSM idealan par
Nanite i VSM su dizajnirani da rade zajedno -- to nije slucajnost vec namera od samog pocetka razvoja UE5. Evo zasto su idealan par:
Nanite renderuje samo ono sto je vidljivo: Nanite koristi cluster-based pristup gde se geometrija deli na male klastere od ~128 trouglova. Za svaki frejm, Nanite odredjuje koji klasteri su vidljivi i renderuje samo njih. Ova ista logika se primenjuje na VSM stranice.
VSM renderuje samo stranice koje su potrebne: Umesto da renderuje celu scenu u shadow map, VSM renderuje samo aktivne stranice. Kombinovano sa Nanite-om, to znaci:
Klasican pristup:
Za svako svetlo:
Renderuj SVU geometriju u shadow map (milioni trouglova)
Nanite + VSM pristup:
Za svako svetlo:
Za svaku POTREBNU stranicu:
Renderuj samo VIDLJIVE KLASTERE Nanite geometrije
koji se preklapaju sa tom stranicom
Razlika je dramaticna. Umesto miliona trouglova, VSM stranica mozda zahteva samo nekoliko hiljada trouglova iz relevantnih Nanite klastera.
31.4.2 Kako Nanite renderuje u VSM stranice
Proces je sledeci:
1. Odredjivanje potrebnih stranica VSM sistem identifikuje sve stranice koje treba renderovati (nove ili invalidated).
2. Frustum za svaku stranicu Svaka shadow stranica od 128 x 128 teksela definise mali frustum u prostoru svetla. Nanite koristi ovaj frustum da odredi vidljivost klastera.
3. Cluster culling Nanite prolazi kroz svoju hijerarhiju klastera i odbacuje (cull-uje) sve klastere koji:
- Ne presecaju frustum stranice
- Su previse mali da budu vidljivi na 128 x 128 rezoluciji
- Su okrenuti ledima svetlu (backface culling)
4. Rasterizacija Preostali klasteri se rasterizuju u shadow stranicu koristeci Nanite-ov softverski rasterizer (za male trouglove) ili hardverski rasterizer (za vece trouglove).
5. Upis u page pool Rezultat rasterizacije se upisuje na odgovarajucu fizicku lokaciju u page pool-u.
31.4.3 Prednosti Nanite klastera za VSM
Nanite-ov cluster-based pristup donosi specificne prednosti za VSM rendering:
- Granularna kontrola -- Nanite moze da renderuje tacno onoliko geometrije koliko jedna stranica zahteva, bez viska
- LOD selekcija -- Nanite automatski bira odgovarajuci LOD nivo za rezoluciju shadow stranice; za daleke stranice, koristi se grublji LOD sto drasticno smanjuje broj trouglova
- Efikasan culling -- Nanite-ova hijerarhija omogucava brzo odbacivanje nerlevantne geometrije za svaku stranicu
- Softverska rasterizacija -- Za male trouglove (koji su cesti u shadow stranicama niske rezolucije), Nanite-ov softverski rasterizer je efikasniji od GPU hardverskog pipeline-a
31.4.4 Non-Nanite geometrija i VSM
VSM nije ekskluzivan za Nanite -- radi i sa obicnom (non-Nanite) geometrijom. Medjutim, postoje razlike:
Nanite geometrija:
- Renderuje se direktno u VSM stranice sa punom efikasnoscu
- Koristi cluster culling za minimalnu cenu
- Automatski LOD baziran na rezoluciji stranice
Non-Nanite geometrija (Skeletal Meshes, particles, itd.):
- Takodje se renderuje u VSM stranice
- Ali se koristi klasican rendering pipeline (vertex + pixel shader)
- Nema prednosti Nanite culling-a i LOD selekcije
- Moze biti skuplje po stranicu, posebno za kompleksnu geometriju
Prakticna implikacija: Dinamicki objekti u UE5 (likovi, animirani objekti) su obicno Skeletal Meshes i ne koriste Nanite. To znaci da su upravo oni najskuplji za VSM rendering -- ali posto ih obicno nema puno, ukupni uticaj je prihvatljiv.
Ovo je dobar primer zasto je u UE5 dizajnu staticno okruzenje (Nanite + kesirane VSM stranice) jeftino, dok su dinamicki elementi (non-Nanite + invalidacija svaki frejm) relativno skuplji.
31.5 Karakteristike performansi
31.5.1 Prvi frejm -- "Cold Start" problem
Kada se scena prvi put ucita ili kada se kamera teleportuje na potpuno novu lokaciju, VSM kes je prazan. Sve potrebne shadow stranice moraju biti renderovane od nule. Ovo se naziva "cold start" i moze uzrokovati primetni stutter ili pad frame rate-a.
Tipican scenario:
Frejm 1 (cold start):
Potrebno stranica: 1500
Kesirano: 0
Treba renderovati: 1500
GPU vreme za senke: 15-30 ms <- SKUPO!
Frejm 2:
Potrebno stranica: 1500
Kesirano: 1450
Treba renderovati: 50
GPU vreme za senke: 1-3 ms <- Normalno
Frejm 3:
Potrebno stranica: 1510
Kesirano: 1495
Treba renderovati: 15
GPU vreme za senke: 0.5-1 ms <- Odlicno
Kako ublaziti cold start:
-
Pre-caching -- Renderujte shadow stranice unapred (pre nego sto ih kamera zaista treba) koristeci:
r.Shadow.Virtual.Cache.PrecachePages 1 -
Postepeno punjenje -- Umesto da se sve stranice renderuju u jednom frejmu, rasporedite ih preko vise frejmova:
r.Shadow.Virtual.MaxPhysicalPagesToCreate [broj] -
Level design -- Izbegavajte nagle teleportacije kamere; koristite prelaze koji daju vremena kesu da se napuni
-
Loading screen -- Tokom loading screen-a, renderujte shadow stranice za pocetnu poziciju kamere
31.5.2 Steady State -- stabilno stanje
U normalnom radu (kamera se polako krece, vecina scene je staticna), VSM je izuzetno efikasan:
- Cache hit rate je tipicno 90-98%
- GPU vreme za senke je 0.5-3 ms (zavisno od kompleksnosti scene i broja dinamickih objekata)
- Ovo je cesto jeftinije od klasicnog CSM-a koji svaki frejm renderuje sve kaskade
31.5.3 Memorijski trosak
VSM koristi GPU memoriju za page pool. Tipicne velicine:
| Podesavanje | Page Pool velicina | Broj fizickih stranica | Preporuceno za |
|---|---|---|---|
| Low | 512 MB | ~32.000 | Slabiji GPU-ovi, mobilni |
| Medium | 1 GB | ~64.000 | Mainstream GPU-ovi |
| High | 2 GB | ~128.000 | High-end GPU-ovi |
| Epic | 4 GB | ~256.000 | Top-tier GPU-ovi |
Dodatna memorija se koristi za:
- Page tables -- relativno mali (nekoliko MB)
- Feedback buffers -- mali (proporcionalni screen resolution)
- Metadata -- informacije o statusu svake stranice
Kontrola velicine page pool-a:
r.Shadow.Virtual.MaxPhysicalPages [broj]
31.5.4 Uticaj broja svetala
Svako svetlo koje baca senke treba svoje VSM stranice. Ovo znaci da veliki broj shadow-casting svetala moze brzo popuniti page pool:
Primer scene:
1 direkcionalno svetlo (sunce): ~500-2000 stranica (clipmap)
10 point svetala sa senkama: ~50-200 stranica svako = 500-2000
5 spot svetala sa senkama: ~20-100 stranica svako = 100-500
---
Ukupno: 1100-4500 stranica aktivnih
Za scene sa mnogo svetala, kljucne optimizacije su:
- Smanjite broj shadow-casting svetala -- Ne mora svako svetlo da baca senke; mnoga mogu koristiti samo osvetljenje bez senki
- Koristite Shadow Distance -- Svetla blizu kamere imaju senke, daleka ih nemaju
- Koristite Shadow Resolution Scale -- Smanjite rezoluciju senki za manje vazna svetla
- Grupno invalidiranje -- Izbegavajte situacije gde se mnogo svetala menja istovremeno
31.5.5 One Pass Shadow Projection vs. Multi-Pass
UE5 nudi dva rezima za shadow projection (primenu senki na osvetljenu scenu):
One Pass Shadow Projection
r.Shadow.Virtual.OnePassProjection 1
- Sve senke od svih svetala se primenjuju u jednom render pass-u
- Efikasnije jer se scena cita samo jednom
- Moze imati vece shader kompleksnosti
- Preporuceno za vecinu scenarija
Multi-Pass Shadow Projection
r.Shadow.Virtual.OnePassProjection 0
- Svako svetlo ima svoj zasebni shadow projection pass
- Vise render pass-ova = vise overhead-a
- Fleksibilnije za debugging i specijalne slucajeve
- Moze biti bolje za scene sa jako puno svetala (zbog shader register pressure-a)
31.5.6 GPU Profiling VSM-a
Za analizu performansi VSM-a, koristite sledece alate:
Unreal Insights:
stat GPU
Trazite kategorije:
ShadowDepths-- vreme renderovanja shadow stranicaVirtualShadowMapProjection-- vreme primene senkiVirtualShadowMapCacheManagement-- overhead kesiranja
RenderDoc / Nsight Graphics: Za detaljnu analizu GPU pass-ova, koristite eksterne GPU profile-re. VSM pass-ovi su jasno oznaceni u captured frame-u.
Konzolne komande za debugging:
r.Shadow.Virtual.ShowStats 1 -- Prikazi statistiku na ekranu
r.Shadow.Virtual.Visualize 1 -- Vizualizuj shadow stranice
r.Shadow.Virtual.ShowClipmapStats 1 -- Statistika clipmap-a
31.6 VSM za razlicite tipove svetla
31.6.1 Direkcionalna svetla -- Clipmap
Kao sto smo detaljno objasnili u sekciji 31.2.3, direkcionalna svetla koriste clipmap pristup.
Kljucne karakteristike:
- Clipmap je centriran oko kamere i pomera se sa njom
- Tipicno 16-24 nivoa clipmap-a, svaki sledeci pokriva duplo vecu oblast
- Najblizi nivo moze imati rezoluciju ekvivalentnu shadow map-u od 32K x 32K
- Najdalji nivo pokriva ogromnu oblast (potencijalno celu mapu) sa niskom rezolucijom
Podesavanja za direkcionalna svetla:
// Broj clipmap nivoa
r.Shadow.Virtual.Clipmap.LevelCount 16
// Rezolucija najblizeg nivoa (u world units po tekselu)
r.Shadow.Virtual.Clipmap.FirstLevel.WorldSize
// Koliko daleko clipmap pokriva
r.Shadow.Virtual.Clipmap.LastLevel.WorldSize
Dan-noc ciklus: Poseban izazov za VSM sa direccionalnim svetlom je dan-noc ciklus. Kada se ugao sunca menja, sve shadow stranice se invalidiraju jer se projekcija svetla promenila. Ovo moze uzrokovati masivne performance spike-ove.
Strategije za ublazavanje:
- Spora promena -- Pomericite sunce polako tako da se u svakom frejmu invalidira samo mali broj stranica
- Kvantizacija ugla -- Menjajte ugao sunca u diskretnim koracima umesto kontinualno (manje cestee ali vece invalidacije)
- Budget limiting -- Ogranicite koliko stranica moze biti renderovano po frejmu
- Prihvatanje nize rezolucije -- Tokom brze promene svetla, privremeno smanjite rezoluciju
31.6.2 Point svetla -- Cubemap stranice
Point svetla (tackasta svetla) emituju svetlost u svim pravcima, sto znaci da im shadow map mora pokriti svih 360 stepeni. Tradicionalno se koriste cubemap shadow maps -- sest shadow map-ova, po jedan za svaku stranu kocke.
VSM primenjuje istu logiku ali virtualno:
Point svetlo VSM struktura:
+------+
| Gore |
| (+Y) |
+------+------+------+------+
| Levo | Napred|Desno | Nazad|
| (-X) | (+Z) | (+X) | (-Z) |
+------+------+------+------+
| Dole |
| (-Y) |
+------+
Svaka strana je virtuelni shadow map
sa sopstvenim stranicama (128x128 teksela svaka)
Kljucne karakteristike za point svetla:
- Svaka strana kocke je poseban virtuelni shadow map
- Stranice se alociraju samo za strane koje su vidljive iz kamere
- Strane koje "gledaju" od kamere obicno ne treba renderovati
- Kesiranje je posebno efektivno jer su point svetla cesto staticna
Optimizacija: Ako je point svetlo staticno (ne pomera se, ne menja intenzitet), sve njegove shadow stranice se renderuju jednom i kesiraju zauvek. Ovo je enormni dobitak za scene sa mnogo staticnih svetala -- npr. osvetljenje enterijera sa desecima tacke svetla.
31.6.3 Spot svetla -- Perspektivne stranice
Spot svetla su najjednostavniji slucaj za VSM jer emituju svetlost u jednom pravcu sa ogranicenim uglom:
Spot svetlo:
Izvor
/|\
/ | \
/ | \
/ | \
/ | \
+-----+-----+
| Virtuelni |
| Shadow Map |
+-------------+
Kljucne karakteristike:
- Jedan virtuelni shadow map po spot svetlu
- Rezolucija zavisi od ugla konusa i rastojanja od kamere
- Obicno zahteva relativno mali broj stranica (20-100)
- Idealne za kesiranje jer su cesto staticne
Podesavanja:
// Rezolucija shadow map-a za spot svetla (indirektno, kroz screen space velicinu)
r.Shadow.Virtual.ResolutionLodBias [vrednost]
31.6.4 Rect svetla (Area Lights)
Rect svetla (pravougaona svetla) se u kontekstu VSM-a tretiraju slicno spot svetlima, ali sa ortografskom projekcijom umesto perspektivne. Ovo ih cini efikasnim za shadow rendering jer ortografska projekcija rezultira uniformnijom raspodelom rezolucije.
31.7 Kvalitet i podesavanja
31.7.1 Pregled kljucnih podesavanja
Evo svih vaznih konzolnih varijabli za kontrolu VSM-a, organizovanih po kategorijama:
Osnovna kontrola
// Ukljuci/iskljuci VSM (0 = iskljuceno, 1 = ukljuceno)
r.Shadow.Virtual.Enable 1
// Rezime kvaliteta senki (Low/Medium/High/Epic/Cinematic)
sg.ShadowQuality [0-4]
Rezolucija i kvalitet
// LOD bias za rezoluciju (negativne vrednosti = visa rezolucija,
// pozitivne = niza)
r.Shadow.Virtual.ResolutionLodBias 0.0
// Minimalna rezolucija stranice (log2)
// Nize vrednosti = manje stranice za daleke/male senke
r.Shadow.Virtual.MinResolutionLevel 6
// Maksimalna rezolucija clipmap nivoa
r.Shadow.Virtual.Clipmap.MaxResolution 4096
Memorija i Page Pool
// Maksimalan broj fizickih stranica u page pool-u
r.Shadow.Virtual.MaxPhysicalPages 4096
// Velicina jedne fizicke stranice u tekselima (ne menjajte osim za eksperimente)
// Default: 128
r.Shadow.Virtual.PageSize 128
// Format dubine za shadow stranice
r.Shadow.Virtual.Use16BitPageTable 1
Kesiranje
// Ukljuci/iskljuci kesiranje
r.Shadow.Virtual.Cache 1
// Dozvoli kesiranje staticke geometrije
r.Shadow.Virtual.Cache.StaticSeparate 1
// Koliko frejmova stranica moze ostati nekoriscena pre eviction-a
r.Shadow.Virtual.Cache.MaxAge 100
// Rastojanje na kom se invalidacija primenjuje
r.Shadow.Virtual.InvalidationDistance 5000
Clipmap (direkcionalna svetla)
// Broj clipmap nivoa
r.Shadow.Virtual.Clipmap.LevelCount 16
// Rastojanje na kom clipmap staje
r.Shadow.Virtual.Clipmap.FarPlane 100000
// Bias za blending izmedju nivoa
r.Shadow.Virtual.Clipmap.TransitionBlendBias 0.5
Shadow Projection
// Jedan pass za sve senke vs. vise pass-ova
r.Shadow.Virtual.OnePassProjection 1
// Kontaktne senke (poboljsava kvalitet senki u kontaktu sa povrsinom)
r.Shadow.Virtual.ContactShadows 1
// Velicina kontaktnih senki
r.ContactShadows.Length 0.02
Performance Budget
// Maksimalan broj stranica za rendering po frejmu
r.Shadow.Virtual.MaxPhysicalPagesToCreate 512
// Budget za ukupno vreme renderovanja senki (u ms)
r.Shadow.Virtual.RenderingBudgetMs 5.0
31.7.2 Preporuceni profili
Evo preporucenih profila podesavanja za razlicite scenarije:
Profil: Visoke performanse (60+ FPS, mainstream GPU)
r.Shadow.Virtual.Enable 1
r.Shadow.Virtual.ResolutionLodBias 1.0
r.Shadow.Virtual.MaxPhysicalPages 2048
r.Shadow.Virtual.Cache 1
r.Shadow.Virtual.Cache.StaticSeparate 1
r.Shadow.Virtual.OnePassProjection 1
r.Shadow.Virtual.MaxPhysicalPagesToCreate 256
r.Shadow.Virtual.Clipmap.LevelCount 12
Profil: Balansiran (30-60 FPS, mid-range GPU)
r.Shadow.Virtual.Enable 1
r.Shadow.Virtual.ResolutionLodBias 0.0
r.Shadow.Virtual.MaxPhysicalPages 4096
r.Shadow.Virtual.Cache 1
r.Shadow.Virtual.Cache.StaticSeparate 1
r.Shadow.Virtual.OnePassProjection 1
r.Shadow.Virtual.MaxPhysicalPagesToCreate 512
r.Shadow.Virtual.Clipmap.LevelCount 16
Profil: Maksimalan kvalitet (bez ogranicenja FPS-a, high-end GPU)
r.Shadow.Virtual.Enable 1
r.Shadow.Virtual.ResolutionLodBias -1.0
r.Shadow.Virtual.MaxPhysicalPages 8192
r.Shadow.Virtual.Cache 1
r.Shadow.Virtual.Cache.StaticSeparate 1
r.Shadow.Virtual.OnePassProjection 1
r.Shadow.Virtual.MaxPhysicalPagesToCreate 1024
r.Shadow.Virtual.Clipmap.LevelCount 20
31.7.3 Podesavanja u Blueprint-u i C++
Osim konzolnih varijabli, neka podesavanja su dostupna i per-light u editoru:
Na DirectionalLight komponenti:
Cast Shadows-- da li svetlo uopste baca senkeShadow Resolution Scale-- mnozilac rezolucije za ovo svetloFar Shadow Cascade Count-- broj daljih kaskada (interakcija sa VSM clipmap-om)Dynamic Shadow Distance-- rastojanje do kog senke postoje
Na PointLight/SpotLight komponenti:
Cast Shadows-- ukljuci/iskljuci senkeShadow Resolution Scale-- mnozilac rezolucijeContact Shadow Length-- duzina kontaktnih senki
Na Static Mesh komponenti:
Cast Shadow-- da li mesh baca senkeShadow Cache Invalidation Behavior-- kontrola invalidacije (Always, Rigid, Static)
U C++ kodu:
// Pristup VSM podesavanjima
#include "VirtualShadowMapClipmap.h"
// Na svetlu
UDirectionalLightComponent* Light = ...;
Light->SetCastShadows(true);
Light->SetShadowResolutionScale(1.0f);
// Globalna kontrola
IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(
TEXT("r.Shadow.Virtual.MaxPhysicalPages")
);
if (CVar)
{
CVar->Set(4096);
}
31.8 Cesti problemi i resenja
31.8.1 Flickering senki (treperenje)
Simptom: Senke trepere -- pojavljuju se i nestaju, ili menjaju oblik izmedju frejmova.
Mogucni uzroci i resenja:
Uzrok 1: Page pool je premali Kada page pool nema dovoljno prostora, stranice se stalno izbacuju i ponovo ucitavaju (thrashing). Ovo izaziva vidljivo treperenje.
// Resenje: povecajte page pool
r.Shadow.Virtual.MaxPhysicalPages 8192
// Proverite statistiku da vidite da li je pool pun:
r.Shadow.Virtual.ShowStats 1
// Trazite "Page Pool Full" ili "Evictions" brojeve
Uzrok 2: Invalidacija koja se ne stabilizuje Neki dinamicki objekti mogu konstantno invalidirati iste stranice. Proverite da li imate objekte koji se "tresu" na mestu (micro-movement od fizike).
// Resenje: podesite threshold za invalidaciju
r.Shadow.Virtual.Cache.InvalidationThreshold 0.01
Uzrok 3: Precision problemi Za vrlo daleke objekte, floating point preciznost moze uzrokovati nestabilno mapiranje na shadow stranice.
// Resenje: podesite far plane clipmap-a
r.Shadow.Virtual.Clipmap.FarPlane 50000
// Ili koristite World Partition sa origin rebasing-om
31.8.2 Nedostajuce senke
Simptom: Neki objekti ne bacaju senke, ili senke nestaju na odredjenim rastojanjima.
Mogucni uzroci i resenja:
Uzrok 1: Page allocation limit dostignut VSM ima limit koliko stranica moze biti alocirano. Kada se limit dostigne, nove stranice se ne alociraju i senke nestaju.
// Resenje: povecajte limite
r.Shadow.Virtual.MaxPhysicalPages 8192
r.Shadow.Virtual.MaxPhysicalPagesToCreate 1024
Uzrok 2: Objekat je previse mali za rezoluciju stranice Ako je objekat toliko mali da ne zauzima ni jedan teksel u shadow stranici na datom rastojanju, njegova senka nestaje.
// Resenje: smanjite LOD bias (povecajte rezoluciju)
r.Shadow.Virtual.ResolutionLodBias -0.5
Uzrok 3: Cast Shadow je iskljucen Trivijalno ali cesto -- proverite da li objekat uopste ima ukljuceno bacanje senki.
Uzrok 4: Shadow distance Objekat je izvan rastojanja na kom svetlo baca senke.
// Proverite na svetlu:
DirectionalLight -> Dynamic Shadow Distance MovableLight
Uzrok 5: Non-Nanite geometrija bez odgovarajuceg podesavanja Neki non-Nanite mesh-ovi mogu zahtevati eksplicitno podesavanje za VSM.
31.8.3 Performance spike-ovi
Simptom: Povremeni padovi frame rate-a povezani sa senkama, posebno pri naglim promenama scene.
Mogucni uzroci i resenja:
Uzrok 1: Masovna invalidacija Mnogo stranica se invalidira odjednom -- npr. vrata se otvore i otkriju veliku novu oblast, ili se ugao sunca naglo promeni.
// Resenje: ogranicite koliko stranica moze biti renderovano po frejmu
r.Shadow.Virtual.MaxPhysicalPagesToCreate 256
// Ovo "razmazuje" trosak preko vise frejmova
// Ali senke nece biti odmah azurirane -- kompromis
Uzrok 2: Mnogo dinamickih objekata invalidira mnogo stranica Veliki broj pokretnih objekata (npr. gomila NPC-ova) moze invalidirati stotine stranica.
// Resenje: smanjite invalidation distance
r.Shadow.Virtual.InvalidationDistance 3000
// Ili iskljucite senke za manje vazne objekte
// na daljem rastojanju
Uzrok 3: Level streaming Ucitavanje novog level-a (streaming) moze odjednom dodati ogromnu kolicinu geometrije, sto zahteva rendering mnogih novih stranica.
// Resenje: pre-cache stranice tokom loading-a
// Ili koristite postupno ucitavanje sa budget limitom
r.Shadow.Virtual.MaxPhysicalPagesToCreate 128
Uzrok 4: Materijali sa opacity mask Materijali koji koriste opacity mask (npr. lisce, ograde) su skuplji za shadow rendering jer zahtevaju pixel shader evaluaciju umesto cistog depth-only renderinga.
// Za Nanite: koristite Masked materijale stedljivo
// Razmislite o upotrebi billboard-a za daleke objekte
// umesto detaljne masked geometrije
31.8.4 Nekonzistentna rezolucija senki
Simptom: Senke imaju primetno razlicitu rezoluciju na razlicitim delovima scene.
Objasnjenje: Ovo je zapravo normalno ponasanje VSM-a. Rezolucija senki zavisi od:
- Rastojanja od kamere (blize = visa rezolucija)
- Velicine na ekranu (veci objekti dobijaju vise stranica)
- Dostupnog prostora u page pool-u
Ublazavanje:
// Smanjite LOD bias za uniformniju rezoluciju
r.Shadow.Virtual.ResolutionLodBias -0.5
// Ali pazite na performance troskove!
31.8.5 Artifakti na ivicama shadow stranica
Simptom: Vidljive linije ili artefakti na mestima gde se shadow stranice spajaju.
Uzrok: Nedovoljan border izmedju stranica, ili preciznost filtriranja.
// Resenje: proverite da su border tekseli pravilno konfigurisani
// Ovo je obicno interno reseno, ali moze se podesiti:
r.Shadow.Virtual.PageBorderSize 4
// Takodje proverite shadow filtering:
r.Shadow.Virtual.SMRT.SamplesPerRay 8
r.Shadow.Virtual.SMRT.RayCount 8
31.8.6 Debug vizualizacija
UE5 nudi odlicne alate za debug vizualizaciju VSM-a:
// Prikazi sve shadow stranice kao overlay
r.Shadow.Virtual.Visualize 1
// Prikazi samo alocirane stranice
r.Shadow.Virtual.Visualize.ModeFlags 1
// Prikazi koje stranice su kesirane vs. sveize renderovane
r.Shadow.Virtual.Visualize.ModeFlags 2
// Prikazi clipmap nivoe razlicitim bojama
r.Shadow.Virtual.Visualize.ModeFlags 4
// Prikazi statistiku na ekranu
r.Shadow.Virtual.ShowStats 1
// Prikazi number of pages per light
r.Shadow.Virtual.ShowLightStats 1
Tumacenje vizualizacije:
- Zeleno -- stranica je uspesno ucitana iz kesa (cache hit)
- Crveno -- stranica je renderovana ovog frejma (cache miss ili invalidacija)
- Plavo -- stranica nije alocirana (van page pool-a)
- Zuto -- stranica ceka na rendering (u redu cekanja)
31.9 Napredne teme
31.9.1 Shadow Map Filtering (SMRT)
VSM koristi Shadow Map Ray Tracing (SMRT) -- ne mesati sa hardverskim ray tracing-om! SMRT je screen-space tehnika filtriranja koja poboljsava kvalitet senki:
- Umesto jednog uzorka iz shadow map-a, SMRT baca vise "zraka" kroz shadow map
- Ovo daje mekse, prirodnije senke na ivicama
- Kvalitet zavisi od broja uzoraka:
// Broj zraka po pikselu
r.Shadow.Virtual.SMRT.RayCount 8
// Broj uzoraka po zraku
r.Shadow.Virtual.SMRT.SamplesPerRay 8
// Ukupno uzoraka = RayCount * SamplesPerRay = 64
// Vise uzoraka = bolji kvalitet ali skuplje
Preporuke:
- Za real-time (igre): RayCount 4-8, SamplesPerRay 4-8
- Za cinematic: RayCount 8-16, SamplesPerRay 8-16
- Za previews: RayCount 2, SamplesPerRay 4
31.9.2 Contact Shadows
Contact Shadows su komplementarna tehnika koja dodaje senke u neposrednom kontaktu izmedju objekata. VSM sam po sebi moze propustiti vrlo sitne senke u kontaktu (npr. tamo gde noga dodiruje pod), pa Contact Shadows to kompenzuju:
// Ukljuci contact shadows
r.ContactShadows 1
// Duzina ray march-a (u screen space)
r.ContactShadows.Length 0.02
// Broj koraka
r.ContactShadows.Steps 8
Contact Shadows se izracunavaju u screen space (koristeci depth buffer -- setite se Poglavlja 9!) i ne koriste VSM page pool. One su odvojen pass koji se dodaje na VSM senke.
31.9.3 Interakcija sa Lumen
Lumen (UE5 global illumination sistem) koristi VSM za svoje shadow podatke. Konkretno:
- Lumen-ovi screen traces koriste VSM za shadow visibility
- Lumen-ovi mesh card traces takodje mogu koristiti VSM podatke
- Ovo znaci da kvalitet VSM-a direktno utice na kvalitet Lumen GI-a
Ako primetite artefakte u indirektnom osvetljenju, proverite VSM podesavanja -- cesto su uzrok nedovoljno stranica ili preniska rezolucija.
31.9.4 VSM i Ray Tracing senke
VSM i hardverski ray tracing senke su alternativni pristupi -- obicno se koristi jedan ili drugi, ne oba za isto svetlo:
| Aspekt | VSM | Ray Traced Shadows |
|---|---|---|
| Kvalitet | Vrlo visok, ali baziran na rasterizaciji | Tacan, per-pixel |
| Performanse | Efikasan uz kesiranje | Skuplji, bez kesiranja |
| Mekse senke | SMRT filtering (aproksimacija) | Fizicki tacne penumbre |
| Transparentnost | Ogranicena (opacity mask) | Potpuna podrska |
| Hardware zahtev | Bilo koji DX11+ GPU | RTX / DXR GPU |
U praksi, VSM je preporucen za vecinu projekata zbog boljeg odnosa performansi i kvaliteta. Ray traced senke su opcija za cinematic kvalitet gde performanse nisu prioritet.
31.9.5 VSM u Multiplayer/Server okruzenju
U multiplayer igrama, VSM se renderuje samo na klijentu (GPU strana). Server nema nikakve veze sa VSM-om jer je to cisto vizuelni sistem. Medjutim, indirektno postoje implikacije:
- Network replication pokretnih objekata utice na VSM invalidaciju
- Predvidjanje pozicije (client-side prediction) moze uzrokovati prolazno treperenje senki ako se korekcija desi naglo
- Level streaming odluke (koje su cesto server-driven) uticu na VSM cold start probleme
31.10 Prakticni saveti i best practices
31.10.1 Tok rada za optimizaciju senki
Evo preporucenog toka rada za optimizaciju VSM-a u vasem projektu:
Korak 1: Pocnite sa default podesavanjima UE5 ima razumne default vrednosti. Nemojte odmah menjati sve -- pustite engine da radi.
Korak 2: Identifikujte probleme
Koristite stat GPU i r.Shadow.Virtual.ShowStats 1 da vidite:
- Koliko stranica je aktivno?
- Koliki je cache hit rate?
- Koliko vremena GPU trosi na senke?
Korak 3: Adresujte najveci problem prvi
- Ako je page pool pun -> povecajte
MaxPhysicalPages - Ako je cache hit rate nizak -> identifikujte sta invalidira stranice
- Ako je GPU vreme visoko -> smanjite rezoluciju ili broj stranica po frejmu
Korak 4: Profile na ciljnom hardware-u Podesavanja koja rade na vasem razvojnom PC-ju mozda nece raditi na ciljnoj platformi. Uvek testirajte na ciljnom hardware-u.
Korak 5: Scalability Koristite UE5 Scalability sistem da definisete razlicite profile za razlicit hardware:
; U DefaultScalability.ini:
[ShadowQuality@0] ; Low
r.Shadow.Virtual.ResolutionLodBias=2.0
r.Shadow.Virtual.MaxPhysicalPages=1024
[ShadowQuality@1] ; Medium
r.Shadow.Virtual.ResolutionLodBias=1.0
r.Shadow.Virtual.MaxPhysicalPages=2048
[ShadowQuality@2] ; High
r.Shadow.Virtual.ResolutionLodBias=0.0
r.Shadow.Virtual.MaxPhysicalPages=4096
[ShadowQuality@3] ; Epic
r.Shadow.Virtual.ResolutionLodBias=-0.5
r.Shadow.Virtual.MaxPhysicalPages=8192
31.10.2 Level Design smernice
-
Koristite Nanite za staticnu geometriju gde god mozete -- ovo maksimizuje efikasnost VSM kesiranja i cluster culling-a
-
Minimizirajte broj shadow-casting svetala -- Svako svetlo sa senkama zahteva sopstvene VSM stranice. Razmislite da li svetlo zaista mora da baca senke.
-
Koristite Light Channels -- Pomocu light channels mozete kontrolisati koja svetla uticu na koje objekte, potencijalno smanjujuci broj potrebnih shadow stranica.
-
Izbegavajte nagle teleportacije kamere -- Cutscene prelazi sa teleportacijom uzrokuju cold start. Koristite brze ali kontinualne pokrete kamere ili mask/fade prelaze.
-
Pazljivo sa dan-noc ciklusom -- Svaka promena ugla sunca invalidira clipmap. Dizajnirajte ciklus sa postepenim promenama.
-
Optimizujte masked materijale -- Lisce, ograde i slicno sa opacity mask su skuplji za shadow rendering. Koristite ih mudro i razmislite o daljim LOD zamena (billboard-i).
-
World Partition i Streaming -- Kada koristite World Partition, budite svesni da streaming novih celija uzrokuje shadow page allocation. Planirajte streaming zonu dovoljno veliku da VSM ima vremena da napuni kes pre nego sto igrac stigne do novih oblasti.
31.10.3 Debugging Checklist
Kada naidjete na problem sa senkama, prodjite kroz ovu listu:
- Da li je VSM ukljucen? (
r.Shadow.Virtual.Enable) - Da li svetlo baca senke? (Cast Shadows na komponenti)
- Da li mesh baca senke? (Cast Shadow na komponenti)
- Kakav je cache hit rate? (
r.Shadow.Virtual.ShowStats 1) - Da li je page pool pun? (stats -> Evictions > 0)
- Da li postoji neocekivana invalidacija? (stats -> Pages Invalidated)
- Da li je objekat unutar shadow distance? (Dynamic Shadow Distance)
- Da li je objekat dovoljno velik za shadow rezoluciju? (ResolutionLodBias)
- Da li je problem specifican za jedan tip svetla? (testirajte svako svetlo pojedinacno)
- Da li problem nestaje sa vise fizickih stranica? (MaxPhysicalPages)
31.11 Poredjenje VSM sa prethodnim sistemima
31.11.1 VSM vs. Cascaded Shadow Maps (CSM)
| Aspekt | CSM | VSM |
|---|---|---|
| Rezolucija | Fiksna po kaskadi | Virtualno neogranicena |
| Memorija | Predvidljiva, fiksa | Dinamicna, page pool |
| Rendering cost po frejmu | Konstantan (sve kaskade) | Varijabilan (zavisi od invalidacije) |
| Kesiranje | Nema (svaki frejm sve) | Agresivno kesiranje |
| Nanite integracija | Nema specijalne | Nativna, cluster-level |
| Kvalitet na dalekom | Los (niska rezolucija) | Dobar (clipmap nivoi) |
| Kaskadni prelazi | Vidljivi artefakti | Nema (glatki nivoi) |
| Kompleksnost | Jednostavno | Kompleksno |
| Cold start | Nema (svaki frejm isto) | Da (prvi frejm skup) |
31.11.2 Kada NE koristiti VSM
VSM nije uvek najbolji izbor. Razmotrite alternative u sledecim slucajevima:
- Jako jednostavne scene -- Ako imate mali broj objekata i niske zahteve za kvalitet senki, CSM moze biti jednostavniji i dovoljno dobar
- Mobilne platforme -- VSM je dizajniran za desktop/konzolne GPU-ove; mobilne platforme mozda nemaju dovoljno GPU memorije ili compute snage
- VR aplikacije -- U VR-u su performance budgeti strozi; VSM moze biti preskup za neke VR projekte (mada UE5 ga i dalje preporucuje kao default)
- Stare platforme -- GPU-ovi bez odgovarajuce compute shader podrske mozda nece moci da pokrenu VSM efikasno
31.12 Povezivanje sa drugim poglavljima
Kao sto smo nagovestili na pocetku, VSM ne postoji u vakuumu -- on je deo sire UE5 rendering arhitekture. Evo kako se povezuje sa temama iz drugih poglavlja:
Poglavlje 9: Depth Buffer
Depth buffer je fundamentalni koncept koji je u osnovi svakog shadow map-a, ukljucujuci VSM. Svaka VSM stranica je u sustini mali depth buffer renderovan iz perspektive svetla. Razumevanje depth preciznosti, Z-fighting-a i depth testiranja (sve pokriveno u Poglavlju 9) direktno se primenjuje na VSM.
Posebno relevantno: reverse-Z tehnika koju UE5 koristi za depth buffer se takodje primenjuje na VSM stranice, obezbjedjujuci maksimalnu preciznost blizu kamere (gde je najvaznija).
Poglavlje 13: Shadow Mapping teorija
Celo Poglavlje 13 postavlja teorijsku osnovu na kojoj VSM gradi. Koncepti kao sto su shadow bias, Peter Panning, percentage closer filtering (PCF), i shadow acne su i dalje relevantni u VSM kontekstu -- samo sto VSM mnoge od tih problema resava ili ublazava kroz visu efektivnu rezoluciju.
Ako imate problema sa razumevanjem zasto neko VSM podesavanje postoji, vratite se na odgovarajucu sekciju u Poglavlju 13 za teorijsku pozadinu.
Poglavlje 30: Nanite
Najdirektija veza. Nanite i VSM su dizajnirani kao komplementarni sistemi. Nanite-ov cluster-based rendering se direktno koristi za efikasno popunjavanje VSM stranica. Ako niste procitali Poglavlje 30, vratite se i procitajte ga -- razumevanje Nanite klastera i LOD selekcije je kljucno za razumevanje zasto je VSM toliko efikasan.
31.13 Rezime poglavlja
Evo najvaznijih tacaka iz ovog poglavlja:
-
VSM je neophodan jer klasicni shadow mapping sistemi (CSM) ne mogu da prate kvalitet Nanite geometrije -- rezolucija je nedovoljna, kesiranja nema, a svaki frejm se sve renderuje iznova.
-
VSM koristi princip virtuelne memorije -- ogroman virtualni shadow map podeljen na male stranice (128x128), od kojih se alociraju i renderuju samo potrebne.
-
Kesiranje je srce performansi -- staticne shadow stranice se renderuju jednom i kesiraju neograniceno; samo dinamicki objekti zahtevaju re-rendering svaki frejm.
-
Nanite i VSM su idealni partneri -- Nanite-ov cluster culling omogucava efikasno renderovanje samo relevantne geometrije za svaku shadow stranicu.
-
Razliciti tipovi svetla koriste razlicite pristupe: clipmap za direkcionalna, cubemap za point, perspektiva za spot -- ali svi koriste isti VSM page pool.
-
Cold start je realan problem -- prvi frejm na novoj lokaciji je skup jer kes mora biti napunjen od nule.
-
Podesavanja su brojna ali najvaznija su:
MaxPhysicalPages(velicina page pool-a),ResolutionLodBias(kvalitet vs. performanse), iMaxPhysicalPagesToCreate(budget po frejmu). -
Debug alati su vasi prijatelji --
ShowStats,Visualize, istat GPUsu neophodni za dijagnostiku problema.
Tabela kljucnih pojmova
| Pojam (engleski) | Opis |
|---|---|
| Virtual Shadow Map (VSM) | Sistem senki u UE5 koji koristi princip virtuelne memorije za efikasno renderovanje senki visoke rezolucije |
| Page | Osnovna jedinica VSM-a; blok od 128x128 teksela koji cuva shadow podatke |
| Page Pool | Fizicki bazen u GPU memoriji gde se cuvaju renderovane shadow stranice |
| Page Table | Indirekciona tabela koja mapira virtuelne stranice na fizicke lokacije u page pool-u |
| Clipmap | Hijerarhijska struktura nivoa razlicite rezolucije, centrirana oko kamere, koriscena za direkcionalna svetla |
| Cache Hit Rate | Procenat shadow stranica uspesno procitanih iz kesa bez potrebe za ponovnim renderovanjem |
| Invalidation | Proces oznacavanja shadow stranice kao neazurne, sto zahteva njeno ponovno renderovanje |
| Cold Start | Situacija kada je kes prazan (npr. prvi frejm ili teleportacija) i sve stranice moraju biti renderovane |
| LRU Eviction | Politika izbacivanja najstarijih nekoriscenih stranica kada je page pool pun (Least Recently Used) |
| SMRT (Shadow Map Ray Tracing) | Tehnika filtriranja senki bazirana na ray marching-u kroz shadow map za mekse ivice |
| Contact Shadows | Screen-space tehnika za dodavanje sitnih senki u kontaktu izmedju objekata |
| Feedback Buffer | Buffer koji belezi koje shadow stranice su potrebne za trenutni frejm |
| One Pass Projection | Rezim u kome se sve senke od svih svetala primenjuju u jednom render pass-u |
| Shadow Bias | Offset primenjenje na shadow test da bi se sprecili self-shadowing artefakti (shadow acne) |
| Cluster Culling | Nanite-ova tehnika odbacivanja nerlevantnih klastera geometrije za datu shadow stranicu |
| Opacity Mask | Materijal koji koristi masku za simulaciju rupa/providnosti (skuplji za shadow rendering) |
| Scalability | UE5 sistem za automatsko prilagodjavanje kvaliteta razlicitom hardware-u |
Korisni linkovi i dalje citanje
-
Epic Games dokumentacija:
- Virtual Shadow Maps -- Zvanicna dokumentacija
- Shadow Mapping in UE5 -- Opsti pregled sistema senki
-
GDC i tehnicke prezentacije:
- "Nanite and Virtual Shadow Maps in UE5" -- GDC prezentacija Epic Games-a
- "Rendering in Unreal Engine 5" -- Brian Karis, SIGGRAPH
-
Blog postovi i clanci:
- Epic Games Tech Blog -- cesto objavljuje detalje o novim rendering feature-ima
- "A Deep Dive into UE5 Virtual Shadow Maps" -- razni tehni cki blogeri su objavili detaljne analize
-
Forumi i zajednica:
- Unreal Engine Forums -- sekcija za rendering
- Unreal Slackers Discord -- kanal #rendering
- Reddit r/unrealengine -- diskusije o optimizaciji
-
Izvorni kod:
- Ako imate pristup UE5 izvornom kodu (besplatan za preuzimanje sa GitHub-a uz Epic nalog), pogledajte:
Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapArray.cpp-- glavna klasaVirtualShadowMapClipmap.cpp-- clipmap implementacijaVirtualShadowMapCacheManager.cpp-- kesiranje
- Ako imate pristup UE5 izvornom kodu (besplatan za preuzimanje sa GitHub-a uz Epic nalog), pogledajte:
Sta dalje?
U sledecem poglavlju cemo istraziti jos jedan kljucni deo UE5 rendering pipeline-a. Sa znanjem o Nanite-u (Poglavlje 30) i Virtual Shadow Maps-u (ovo poglavlje), imate solidnu osnovu za razumevanje kako UE5 postize vizuelni kvalitet koji rivalizuje filmskoj produkciji -- uz performanse dovoljne za interaktivne aplikacije.
Pre nego sto predjete dalje, preporucujem da:
- Otvorite UE5 projekat sa Nanite geometrijom
- Ukljucite
r.Shadow.Virtual.ShowStats 1ir.Shadow.Virtual.Visualize 1 - Prosetajte se po sceni i posmatrajte kako se stranice alociraju i kesiraju
- Eksperimentisite sa podesavanjima iz sekcije 31.7
- Pokusajte da namerno izazovete probleme iz sekcije 31.8 i vezbajte njihovo resavanje
Prakticno iskustvo je nezamenjivo -- citanje o VSM-u je korisno, ali pravo razumevanje dolazi tek kada vidite kako se stranice crtaju u realnom vremenu dok hodate kroz svoju scenu.
Srecno sa eksperimentisanjem, i vidimo se u sledecem poglavlju!
Poglavlje 31 -- Virtual Shadow Maps | Unreal Engine 5: Od nule do heroja