Poglavlje 13: Senke (Shadows)

Poglavlje 13: Senke (Shadows)

U ovom poglavlju razumes zasto su senke toliko bitne za uverljivost scene, kako se one zapravo racunaju u real-time renderovanju, i koje tehnike Unreal Engine 5 koristi da bi ti pruzio sirokopaletu opcija -- od klasicnih shadow mapa, preko cascaded i virtual shadow mapa, do ray-traced i contact senki. Ovo poglavlje je most izmedju teorije osvetljenja (Poglavlje 10-12) i prakticnih sistema za senke u UE5 (Poglavlje 31).


Uvod: Svet bez senki

Zamisli sledecu scenu: stojis na suncu, usred parka. Ispred tebe je klupa. Na klupi sedi covek. Drvo baca dugacku senku na travu. Senka klupe se prostire po stazi. Covekova senka pada na naslon klupe i blago na travu iza nje.

Sada zamisli tu istu scenu, ali potpuno bez senki. Klupa, covek, drvo -- svi postoje, svi su osvetljeni, ali nijedna senka ne postoji. Sta se desava?

Odjednom, klupa "lebdi". Ne mozes da kazes da li je na zemlji ili metar iznad nje. Covek izgleda kao da je nalepljen na sliku klupe -- nemas osecaj da on zaista sedi na njoj. Drvo gubi trodimenzionalnost -- kruna deluje ravno, kao kartonski izrez. Cela scena izgleda kao losPhotoshop montaza gde su razliciti elementi nalepi jedni na druge bez ikakvog smisla za prostor.

Ovo nije preterivanje. Senke su jedan od najvaznijih vizuelnih signala koje nas vizuelni sistem koristi da bi rekonstruisao 3D prostor iz 2D slike na retini (ili na monitoru). Bez senki, gubimo:

  1. Uzemljenje objekata (grounding). Senka na podu ispod objekta je signal mozgu da je objekat na podu. Bez te senke, objekat vizuelno lebdi.

  2. Prostorne odnose izmedju objekata. Senka jednog objekta koja pada na drugi govori ti o njihovom relativnom polozaju u prostoru. Ako senka coveka pada na klupu, znas da je covek blizu klupe i da je svetlo dolazi sa odredjene strane.

  3. Percepciju dubine. Senke su mocan signal dubine -- jacak od mnogih drugih (kao sto su perspektiva ili atmosferska perspektiva) u odredjenim situacijama. Eksperimenti u psihologiji percepcije su pokazali da promena samo senke moze da dovede do toga da isti objekat izgleda kao da je na potpuno drugoj poziciji u prostoru.

  4. Oblik povrsina. Self-shadowing -- senka koju objekat baca sam na sebe -- otkriva oblik povrsine. Bore na odeci, tekstura kamena, udubljenja na terenu -- sve ovo postaje vidljivo prvenstveno zahvaljujuci senkama.

  5. Vreme dana i atmosferu. Duzina i pravac senki govore ti o polozaju sunca. Ostre senke sugerisu jako direktno svetlo; meke senke sugerisu oblacno vreme ili velike izvore svetlosti.

Ukratko: bez senki, slika gubi prostornost, uverljivost i citljivost. Zato je renderovanje senki jedna od najvaznijih tema u real-time grafici, i zato ovom poglavlju posvecujemo detaljan tretman.


13.1 Osnove: Sta je senka, matematicki?

Definicija

Senka nastaje kada neka geometrija blokira svetlost da stigne do neke povrsine. Matematicki, to je pitanje vidljivosti izmedju tacke na povrsini i izvora svetlosti.

Za datu tacku P na nekoj povrsini i izvor svetlosti L, postavljamo pitanje: da li postoji ikakva geometrija na putu izmedju P i L? Ako postoji -- P je u senci tog svetla. Ako ne postoji -- P je osvetljen.

Ovo se moze izraziti kao visibility function V(P, L):

V(P, L) = 1    ako je put od P do L slobodan (nema prepreka)
V(P, L) = 0    ako nesto blokira put od P do L

Jednacina za direktno osvetljenje sa ukljucenim senkama postaje:

L_direct(P) = V(P, L) * L_light * f_r(P, ω_i, ω_o) * cos(θ_i)

Gde je V(P, L) mnozilac koji "iskljucuje" svetlo ako je tacka u senci. Ovo je idealizovani slucaj za tackastu svetlost (point light) i daje ostra senke (hard shadows) -- ili si potpuno osvetljen, ili si potpuno u senci, bez prelaza.

Hard shadows vs soft shadows

U stvarnom svetu, potpuno ostre senke skoro da ne postoje. Zasto? Zato sto pravi izvori svetlosti imaju konacnu velicinu -- sunce nije tacka na nebu, vec disk koji zauzima oko 0.53 stepena ugla. Sijalica nije tacka, vec balon od stakla sa zhavicom unutra.

Kada izvor svetlosti ima konacnu velicinu, nastaju tri zone:

Velicina penumbre zavisi od:

  1. Velicine izvora svetlosti -- veci izvor = sira penumbra = mekse senke
  2. Rastojanja od blokirajuce geometrije do prijemne povrsine -- vece rastojanje = sira penumbra
  3. Rastojanja od izvora svetlosti do blokirajuce geometrije

Ovo je dobro poznato pravilo u fotografiji: ako zelis mekse senke, koristi veci izvor svetlosti i pomeri objekat dalje od pozadine.

Za renderovanje, meke senke su znacajno skuplje jer za svaku tacku moras da proveri vidljivost prema vise tacaka na povrsini izvora svetlosti, umesto prema jednoj tacki. Ovo je fundamentalni tradeoff u svim tehnikama senki: ostrina vs cena.

Senke u kontekstu render pipeline-a

Gde se senke racunaju u render pipeline-u koji smo obradili u Poglavlju 07? U tradicionalnom deferred rendering pipeline-u (koji UE5 koristi), senke se racunaju tokom lighting pass-a. Za svaki piksel, za svako svetlo, proverava se da li je piksel u senci tog svetla, i rezultat se koristi kao mnozilac za osvetljenje.

Ali da bi ta provera bila moguca, moramo prvo da znamo gde su senke. I tu dolazimo do prve i najvaznije tehnike za racunanje senki u real-time grafici.


13.2 Shadow Mapping -- dominantna tehnika

Koncept

Shadow mapping je tehnika koju je Lance Williams opisao 1978. godine u radu "Casting Curved Shadows on Curved Surfaces", i od tada je postala apsolutno dominantna metoda za racunanje senki u real-time grafici. Gotovo svaka igra u poslednjih 25 godina koristi neku varijantu shadow mappinga. Razlog za to je sto je tehnika relativno jednostavna za implementaciju, dobro se mapira na GPU hardver, i daje prihvatljive rezultate.

Osnovna ideja je genijalnosjednostavna:

Ako nesto vidi svetlo, ono je osvetljeno. Ako svetlo ne moze da ga "vidi", ono je u senci.

Ovo vodi do dvoprolaznog algoritma:

Prolaz 1: Renderuj scenu iz perspektive svetla

Postavi "kameru" na poziciju svetla, sa pogledom u pravcu svetla. Renderuj celu scenu, ali ne racunaj boje -- samo sacuvaj dubinu (depth) svakog piksela. Rezultat je tekstura koja se zove shadow map -- u sustini, depth buffer gledano iz perspektive svetla.

Ako se secas Poglavlja 09 gde smo detaljno obradili depth buffer, koncept je isti: za svaki piksel u shadow mapi, cuvamo rastojanje od svetla do najblize povrsine u tom pravcu. Shadow mapa ti govori: "iz ovog pravca, najbliza povrsina je na rastojanju D."

Za directional light (poput sunca), koristimo ortografsku projekciju jer su zraci paralelni. Za point light, moramo da renderujemo u sest pravaca (cubemap shadow map). Za spot light, koristimo perspektivnu projekciju sa uglom koji odgovara konusu spot svetla.

Ovde se koriste koncepti iz Poglavlja 06 -- transformacija u "light space" je potpuno analogna transformaciji u camera/view space, samo sto umesto kamere koristimo svetlo kao referentnu tacku.

Prolaz 2: Testiraj svaki piksel glavne slike

Tokom glavnog renderovanja scene (iz perspektive kamere), za svaki piksel:

  1. Uzmi 3D poziciju tog piksela u world space-u (iz G-buffer-a u deferred renderingu, ili iz vertex shader-a u forward renderingu).
  2. Transformisi tu poziciju u light space -- isti koordinatni prostor u kome je shadow mapa renderovana.
  3. Uzmi X i Y koordinate u light space-u kao UV koordinate za sampling shadow mape.
  4. Uzmi Z koordinatu u light space-u -- ovo je rastojanje tog piksela od svetla.
  5. Procitaj vrednost iz shadow mape na tim UV koordinatama -- ovo je rastojanje najblize povrsine od svetla u tom pravcu.
  6. Uporedi: Ako je rastojanje piksela (Z) vece od rastojanja u shadow mapi, to znaci da postoji nesto blize svetlu u tom pravcu -- nesto blokira svetlost -- piksel je u senci.
depth_pixel = rastojanje piksela od svetla (Z u light space)
depth_shadow_map = vrednost procitana iz shadow mape

if (depth_pixel > depth_shadow_map):
    piksel je u SENCI (V = 0)
else:
    piksel je OSVETLJEN (V = 1)

To je to. Cela tehnika se svodi na: renderuj dubinu iz perspektive svetla, pa uporedi sa dubinom svakog piksela u glavnom renderu.

Vizuelni primer

Zamisli scenu: sunce sija sa leve strane, i imas kutiju na ravnom terenu.

Shadow map (renderovano iz perspektive sunca):

Glavni render (iz perspektive kamere):

Rezolucija shadow mape i kvalitet

Shadow mapa je tekstura, i kao svaka tekstura, ima konacnu rezoluciju. Tipicne rezolucije su:

Rezolucija Velicina u memoriji (32-bit depth) Kvalitet
512x512 1 MB Nizak -- vidljive blokaste senke
1024x1024 4 MB Prihvatljiv za manje svetlosti
2048x2048 16 MB Dobar za glavna svetla
4096x4096 64 MB Visok kvalitet, skupo
8192x8192 256 MB Veoma visok, retko se koristi kao jedna mapa

Problem je fundamentalan: shadow mapa pokriva odredjenu oblast sveta, i njena rezolucija odredjuje koliko detalja moze da uhvati. Ako shadow mapa rezolucije 2048x2048 pokriva oblast od 200x200 metara (sto je tipicno za sunce u outdoor sceni), svaki teksel shadow mape pokriva 200/2048 ≈ 0.1 metar = 10 cm u svetu. To znaci da senke ne mogu da uhvate detalje manje od 10 cm -- senka lista na travi bi bila blokasta ili potpuno nevidljiva.

Ovo je fundamentalno ogranicenje shadow mappinga i motivacija za sve naprednije tehnike koje cemo obraditi u nastavku.

Format shadow mape

Shadow mape koriste formate koji cuvaju dubinu sa visokom preciznoscu:

UE5 podrazumevano koristi 16-bit shadow mape za performanse, ali mozes promeniti ovu vrednost u postavkama projekta.


13.3 Artefakti shadow mappinga

Shadow mapping je koncept koji je lep u teoriji, ali pun zamki u praksi. Postoji nekoliko klasicnih artefakata koje moras da razumes, jer ces ih sigurno videti u svom radu.

Shadow acne (samosencenje)

Ovo je verovatno najcesci i najiritantniji artefakt. Izgleda ovako: na povrini koja bi trebalo da bude ravnomerno osvetljena, pojavljuju se nasumicni crni "moire" uzorci -- zebra-like pruge ili tacke senke.

Zasto se desava?

Shadow mapa ima konacnu rezoluciju. Svaki teksel shadow mape pokriva odredjenu oblast povrsine. Kada radis poredjenje dubine za piksel koji se nalazi na toj istoj povrsini, dubina piksela i dubina u shadow mapi bi trebalo da budu jednake. Ali nisu -- iz dva razloga:

  1. Diskretizacija: Shadow mapa cuva jednu vrednost dubine za ceo teksel, a teksel pokriva oblast koja moze da sadrzi blago variraju dubinu (povrsina nije savrseno planarna na nivou jednog teksela).

  2. Razliciti uglovi gledanja: Shadow mapa je renderovana iz perspektive svetla, a glavni render je iz perspektive kamere. Ove dve perspektive "uzorkuju" istu povrsinu pod razlicitim uglovima, sto dovodi do toga da se dubine ne poklapaju savrseno.

Rezultat: za neke piksele, izracunata dubina je marginalno veca od dubine u shadow mapi -- iako bi trebalo da budu iste. Algoritam to interpretira kao "ovaj piksel je u senci", i dobijas laznu senku.

Resenje: Shadow bias

Dodaj mali offset (bias) dubini pre poredjenja:

if (depth_pixel > depth_shadow_map + bias):
    piksel je u senci
else:
    piksel je osvetljen

Bias efektivno "pomera" shadow mapu malo dublje, dajuci prostora za geesku izmedju izracunate i stvarne dubine. Tipicne vrednosti biasa su veoma male -- 0.001 do 0.01 u normalized depth prostoru.

Peter Panning

Ovo je artefakt koji nastaje kada je bias previsok. Kada shadow mapu pomeri previse duboko, senka pri osnovi objekta nestaje -- objekat izgleda kao da "lebdi" iznad terena, jer senka pocinje na odredjenom rastojanju od objekta umesto tacno ispod njega. Efekat je nazvan po Petru Panu jer objekat, poput Petra Pana, lebdi iznad svoje senke.

Dakle, imamo klasican problem balansa:

Pravi bias je negde izmedju, i cesto zavisi od scene. Razlicite povrsine, razliciti uglovi svetla, razlicite udaljenosti od kamere -- sve to utice na optimalni bias.

Slope-scale bias

Pametnija varijanta biasa koja resava deo problema. Umesto fiksnog biasa, bias se skalira prema uglu izmedju povrsine i pravca svetla.

Zasto? Zato sto je shadow acne gori kada svetlo pogadja povrsinu pod malim uglom (grazing angle). U tom slucaju, jedan teksel shadow mape pokriva veliku oblast povrsine, i razlika u dubini izmedju piksela unutar tog teksela je velika. Potreban je veci bias. Kada svetlo pogadja povrsinu direktno (frontalno), problem je manji i potreban je manji bias.

effective_bias = constant_bias + slope_scale_bias * tan(angle)

Gde je angle ugao izmedju normale povrsine i pravca svetla. Ovo automatski povecava bias za povrsine pod malim uglom (gde je tan(angle) veliki) i smanjuje ga za povrsine pod direktnim uglom.

UE5 koristi slope-scale bias kao podrazumevani pristup.

Normal offset bias

Jos jedna tehnika za borbu sa shadow acne. Umesto da pomeras dubinu, pomeras poziciju tacke duz njene normale pre nego sto je projiciras u light space.

adjusted_position = position + normal * normal_offset

Ovo efektivno "podize" tacku sa povrsine za mali iznos pre testiranja senke. Prednost je sto ne utice na dubinu direktno, vec menja poziciju uzorkovanja u shadow mapi. Ovo bolje funkcionise za povrsine pod malim uglom prema svetlu.

U praksi, UE5 kombinuje vise bias tehnika za optimalne rezultate.

Aliasing (blokaste ivice senki)

Shadow mape su diskretne teksture, sto znaci da ivice senki imaju stepen granularnosti -- "stepenice" (staircase) efekat. Ovo je posebno uocljivo za senke blizu kamere, gde je odnos izmedju piksela na ekranu i teksela u shadow mapi najnepovoljniji.

Zamislite: shadow mapa od 2048x2048 pokriva oblast od 100x100 metara. Ako je kamera blizu terena i gleda pod malim uglom, jedan teksel shadow mape moze da pokriva oblast od vise piksela na ekranu. Ivica senke koja u shadow mapi zauzima jednu granicu teksela na ekranu zauzima grub, blokast, nazubljen rub.

Ovo je motivacija za filtriranje shadow mapa, o cemu cemo uskoro detaljno.

Shadow swimming (plivanje senki)

Ovo je artefakt specifican za dinamicne svetlosti (posebno directional light / sunce) i cascade shadow mape. Kada se kamera pomera, senke se blago pomeraju -- "plivaju" po povrsini. Ovo se desava jer se shadow mapa reprojicira svaki frejm, i zbog konacne rezolucije, diskretna mapa se svaki put malo drugacije poklapa sa geometrijom.

Resenje je snapping -- zaokruzivanje pozicije shadow mape na granice teksela, tako da se shadow mapa uvek poklapa na isti nacin. UE5 ovo radi automatski za cascaded shadow mape.


13.4 Filtriranje shadow mapa

Sirove shadow mape daju binaran rezultat: piksel je ili u senci (0) ili je osvetljen (1). To rezultuje u ostrim, aliasovanim ivicama senki. Da bi se dobio glatkiji prelaz, koriste se tehnike filtriranja.

Zasto ne mozes samo da blur-ujes shadow mapu

Na prvi pogled, logicno resenje je da primenis blur filter na shadow mapu pre koriscenja. Ali ovo ne radi korektno. Shadow mapa sadrzi dubine, ne boje. Ako blur-ujes dubine, dobijas prosecne dubine, sto dovodi do pogresnih rezultata -- objekti koji bi trebalo da budu u senci dobijaju svetlost, i obrnuto.

Recimo da imas zid i teren iza njega. Shadow mapa cuva dubinu zida (mali D) i dubinu terena (veliki D). Ako blur-ujes, dobijes prosecnu vrednost koja je negde izmedju -- sto ni za zid ni za teren ne daje tacno poredjenje.

PCF -- Percentage Closer Filtering

PCF je standardna tehnika za filtriranje shadow mapa i koristi se u UE5 kao podrazumevani filter. Ideja je jednostavna ali elegantna:

Umesto da uzorkujes shadow mapu na jednoj poziciji i dobijes binaran rezultat, uzorkuj na vise pozicija oko te pozicije, izvrsi poredjenje dubine za svaku, i usrednji rezultate.

shadow = 0
for each sample (u, v) in filter kernel:
    depth_sample = shadow_map.sample(u, v)
    if (depth_pixel > depth_sample + bias):
        shadow += 1  // u senci
    else:
        shadow += 0  // osvetljen

shadow /= number_of_samples  // prosecna vrednost

Kljucna razlika u odnosu na obicno filtriranje: prvo poredis, pa usrednjavas (percentage closer), umesto da prvo usrednjavas dubine pa onda poredis. Ovo daje korektan rezultat -- na ivici senke, neki uzorci su u senci a neki nisu, i prosecna vrednost daje gladak prelaz.

Tipicni PCF kerneli:

Velicina kernela Broj uzoraka Kvalitet Cena
2x2 4 Minimalan, jos uvek blokasto Jeftino
3x3 9 Prihvatljiv Umereno
5x5 25 Dobar Skuplje
7x7 49 Veoma gladak Skupo
Poisson disk 8-32 (randomizovano) Gladak, manje pravilnih uzoraka Umereno-skupo

Veci kernel = meksa ivica senke, ali i skuplje. Takodje, PCF daje uniformnu mekocu -- ivica senke je jednako meka svuda, bez obzira na rastojanje od blokirajuceg objekta. U realnosti, senke su ostre blizu kontaktne tacke i postaju mekse sa rastojanjem. PCF ovo ne simulira.

UE5 podrazumevano koristi 5x5 PCF kernel za obicne shadow mape, sa varijantama velicine u zavisnosti od tipa svetla i kvalitetnih podesavanja.

PCSS -- Percentage Closer Soft Shadows

PCSS je prosirenje PCF-a koje pokusava da simulira fizicki korektnu mekocu senki -- ostre senke blizu kontakta i meke senke daleko od kontakta.

Algoritam ima dva koraka:

Korak 1: Blocker search (pretrazivanje blokirajuce geometrije)

Za svaku tacku, pretrazi shadow mapu u okolini da bi pronasao prosecnu dubinu geometrije koja blokira svetlost. Ovo ti daje informaciju o tome koliko je blokirajuca geometrija daleko od te tacke.

Korak 2: Varijabilni PCF

Koristi procenjeno rastojanje do blokirajuce geometrije da odredis velicinu PCF kernela. Blize blokirajucej geometriji (malo rastojanje) = mali kernel = ostra senka. Dalje od blokirajuce geometrije (veliko rastojanje) = veliki kernel = meka senka.

Velicina penumbre se racuna na osnovu slicnih trouglova:

penumbra_size = light_size * (d_receiver - d_blocker) / d_blocker

Gde je:

PCSS daje znacajno realticnije senke od obicnog PCF-a, ali je skuplji jer zahteva dva prolaza -- blocker search moze biti skup ako se pretrazuje velika oblast.

UE5 podrzava PCSS za point i spot light-ove, i mozes ga ukljuciti per-light kroz Source Radius parametar na svetlu.


13.5 Cascade Shadow Maps (CSM) -- senke za directional light

Problem

Directional light (sunce) osvetljava celu scenu. Shadow mapa za directional light mora da pokrije ceo vidljivi svet. Ali, kao sto smo videli, shadow mapa ima konacnu rezoluciju. Ako jednom shadow mapom pokrijemo ceo view frustum -- od objekata neposredno ispred kamere do planina na horizontu -- rezolucija po pikselu ekrana bice katastrofalno niska za objekte blizu kamere.

Hajde da to kvantifikujemo. Zamisli da imas shadow mapu od 2048x2048 teksela i da tvoj view frustum pokriva oblast duboku 1000 metara. Blizu kamere, na rastojanju od 1 metra, jedan teksel shadow mape pokriva ogromnu oblast na ekranu, jer je blizi objekat perspektivno veci. Na rastojanju od 1000 metara, isti teksel pokriva manji deo ekrana. Rezultat: senke blizu kamere su grube i blokaste, dok senke u daljini (gde ih ionako slabije vidis) imaju vise nego dovoljno rezolucije.

Ovo je klasican problem perspektivnog aliasinga za shadow mape.

Resenje: podeli frustum na kaskade

Cascade Shadow Maps (CSM) resavaju ovaj problem elegantnomidejom: podeli view frustum na vise segmenata (kaskada), i za svaku kaskadu koristi zasebnu shadow mapu.

Kamera
  |
  |   Kaskada 0        Kaskada 1          Kaskada 2           Kaskada 3
  |   (0-10m)          (10-30m)           (30-100m)           (100-300m)
  |   [2048x2048]      [2048x2048]        [2048x2048]         [2048x2048]
  |   Visoka rez.      Srednja rez.       Niza rez.           Najniza rez.
  |   (ali pokriva     (pokriva           (pokriva            (pokriva
  |    malu oblast)     vecu oblast)       veliku oblast)      najvecu oblast)
  v

Svaka kaskada ima istu rezoluciju shadow mape (npr. 2048x2048), ali pokriva razlicitu velicinu oblasti. Kaskada 0 pokriva najblizy oblast (npr. 0-10 metara od kamere) -- mala oblast, ali sa visokom rezolucijom po pikselu ekrana. Kaskada 3 pokriva najdalju oblast (npr. 100-300 metara) -- velika oblast, ali sa nizom efektivnom rezolucijom, sto je prihvatljivo jer su ti objekti daleko i mali na ekranu.

Distribucija kaskada

Kako odrediti granice kaskada? Postoje dva osnovna pristupa:

Logaritamska distribucija:

split_i = near * (far / near) ^ (i / num_cascades)

Ovo daje vise rezolucije bliskim objektima, sto odgovara perspektivnoj projekciji. Splitovi su: 1, 3.16, 10, 31.6, 100 (za 4 kaskade sa near=1, far=100).

Uniformna distribucija:

split_i = near + (far - near) * (i / num_cascades)

Splitovi su ravnomerno rasporedeni: 1, 25.75, 50.5, 75.25, 100.

Prakticna distribucija (ono sto vecina engine-a koristi, ukljucujuci UE5):

split_i = lerp(uniform_split, logarithmic_split, lambda)

Gde je lambda parametar izmedju 0 i 1 koji kontrolise balans. UE5 daje umetniku kontrolu nad distribucijom kaskada.

Blending izmedju kaskada

Na granici izmedju dve kaskade postoji nagli prelaz kvaliteta -- senka koja je renderovana u visoj rezoluciji (kaskada 0) odjednom prelazi u nizu rezoluciju (kaskada 1). Ovaj prelaz moze biti vidljiv kao nagla promena ostrine senke.

Resenje je cascade blending -- na prelazu izmedju kaskada, uzorkuj obe shadow mape i interpoliraj rezultat. UE5 ima opciju Shadow Cascade Blend Fraction koja kontrolise sirinuprelazne zone.

if (distance < cascade_0_end - blend_zone):
    koristi cascade 0
elif (distance < cascade_0_end):
    blend = (distance - (cascade_0_end - blend_zone)) / blend_zone
    result = lerp(cascade_0_shadow, cascade_1_shadow, blend)
elif (distance < cascade_1_end - blend_zone):
    koristi cascade 1
...

Performansna cena CSM-a

CSM zahteva renderovanje scene vise puta -- jednom za svaku kaskadu. Za 4 kaskade, to znaci 4 dodatna prolaza geometrije. Ovo moze biti veoma skupo, posebno za scene sa velikom kolicinom geometrije.

Tipicna cena:

Komponenta Cena
Svaka kaskada Jedan geometry pass (vertex processing za svu vidljivu geometriju u toj kaskadi)
4 kaskade 4 dodatna geometry pass-a
Shadow map memorija 4 * rezolucija^2 * bytes_per_texel
Sampling u lighting pass-u Dodatno uzorkovanje tekstura (1-4 shadow mape po pikselu)

Ovo je razlog zasto je broj kaskada vazan. Vise kaskada = bolji kvalitet = ali veca cena. UE5 podrazumevano koristi Dynamic Shadow Cascades gde mozes da podesavas broj kaskada (tipicno 2-4) i rastojanja.

CSM u UE5

UE5 koristi CSM za directional light shadow-e u forward rendering modu i kao fallback u Lumen/Nanite pipeline-u. Kljucna podesavanja na Directional Light-u:

Medjutim, sa pojavom Nanite-a i miliona poligona u sceni, CSM postaje preskup jer mora da renderuje svu tu geometriju vise puta. Ovo je direktna motivacija za Virtual Shadow Maps.


13.6 Virtual Shadow Maps (VSM) -- revolucija u UE5

Zasto su nastale

CSM ima fundamentalan problem koji postaje posebno akutan sa Nanite-om: moras da renderujes celu scenu (ili veliki deo scene) u svaku kaskadu, svaki frejm. Kada Nanite scena ima milione ili desetine miliona trouglova, renderovanje 4 kaskade znaci renderovanje tih trouglova cetiri puta samo za senke. To je ogromna cena.

Pored toga, CSM ima ogranicen broj kaskada (tipicno 4), sto znaci da postoji ogranicenje koliko fino mozes da rasporedis rezoluciju. A za lokalne svetlosti (point, spot), CSM se uopste ne koristi -- koristi se jedna shadow mapa, sto za velike point light-ove moze da ima veoma nisku efektivnu rezoluciju.

Virtual Shadow Maps (VSM) su potpuno novi pristup senkama u UE5, dizajniran od nule da radi sa Nanite-om. Cilj: shadow mape ekstremno visoke rezolucije, dovoljne za bilo koji nivo geometrijskog detalja, sa predvidljivom i razumnom performansnom cenom.

Koncept: virtuelna shadow mapa visokog rezolucije

Zamisli shadow mapu rezolucije 16384 x 16384 (16K). To je 268 miliona teksela -- ogromno. Ali umesto da zaista alociras i renderas tu celu mapu, koristi princip slican virtuelnom memorijskom sistemu u operativnom sistemu:

  1. Podeli tu veliku mapu na stranice (pages) od 128x128 teksela.
  2. 16K mapa ima 128x128 = 16384 stranica.
  3. Samo alociraj i renderuj stranice koje su stvarno potrebne -- one koje pokrivaju povrsine vidljive iz kamere.

Ovo je sustina VSM sistema: umesto da renderas celu shadow mapu svaki frejm, renderujes samo one delove (stranice) koji su relevantni.

Clipmap struktura

Za directional light (sunce), VSM koristi clipmap strukturu -- niz nivoa sa razlicitom rezolucijom, centriranih na kameru. Ovo je slicno MIP mapama za teksture, ali za shadow mape.

Nivo 0 (najfiniji): 16K x 16K, pokriva oblast od ~50m oko kamere
    → svaki teksel pokriva ~3mm sveta
Nivo 1: 16K x 16K, pokriva oblast od ~100m
    → svaki teksel pokriva ~6mm sveta
Nivo 2: 16K x 16K, pokriva oblast od ~200m
    → svaki teksel pokriva ~12mm sveta
...
Nivo N (najgrublji): 16K x 16K, pokriva celu scenu
    → svaki teksel pokriva vise metara sveta

Svaki nivo je virtuelna 16K mapa, ali samo mali procenat stranica je zaista alociran u memoriji. Blizu kamere, koristi se najfiniji nivo (Nivo 0) sa najvisom rezolucijom. Dalje od kamere, koriste se grublji nivoi. Ovo je analogno CSM-u, ali sa znacajno vecim brojem "kaskada" i finocom prelaza.

Za lokalne svetlosti (point, spot), VSM koristi slican pristup, ali sa jednom virtuelnom mapom po svetlu.

Stranica od 128x128 teksela

Svaka stranica (page) u VSM sistemu je 128x128 teksela. Ova velicina nije slucajna:

Kako VSM odlucuje koje stranice da renderuje

Svaki frejm, VSM sistem radi sledece:

  1. Analiza vidljivosti: Za svaki piksel na ekranu, odredi koja VSM stranica mu je potrebna. Ovo se radi u screen space-u, koristeci depth buffer glavne slike.

  2. Zahtevi za stranicama: Prikupi skup svih potrebnih stranica (stranice koje pokrivaju vidljive povrsine).

  3. Provera kesa: Proveri da li su te stranice vec renderovane i kesirane iz prethodnog frejma.

  4. Renderovanje novih/nevazecih stranica: Samo renderuj stranice koje su nove (nisu u kesu) ili koje su invalidated (geometrija u toj stranici se promenila -- objekat se pomerio, rotirao, nestao, itd.).

  5. Compositing: Sastavi finalne shadow rezultate iz renderovanih stranica.

Caching i invalidation -- kljuc performansi

Ovo je mozda najvaznija osobina VSM sistema: kesiranje stranica izmedju frejmova.

U tipicnoj sceni, vecina geometrije je staticna -- teren, zgrade, drvo, stene se ne pomeraju. Shadow mape za ovu geometriju ne treba ponovo renderovati svaki frejm. VSM sistem kesira renderovane stranice i samo ih ponovo koristi.

Invalidation (ponistavanje kesa) se desava kada:

U praksi, za tipicnu outdoor scenu gde se kamera lagano krece a vecina objekata je staticna, samo 5-20% stranica se rerenderuje svaki frejm. Ovo je ogromna usteda u poredjenju sa CSM-om, gde se cela shadow mapa rerenderuje svaki frejm.

Integracija sa Nanite-om

VSM je dizajniran da radi ruku pod ruku sa Nanite-om. Kada VSM sistem treba da renderuje stranicu, koristi Nanite-ov rasterizer za renderovanje geometrije u tu stranicu. Ovo je kljucno jer:

  1. Nanite automatski bira pravi LOD za svaku stranicu, na osnovu velicine teksela. Stranice na daljem clipmap nivou dobijaju grublji LOD, stranice na bliskom nivou dobijaju finiji LOD. Ovo znaci da se u shadow mapu renderuje samo onoliko geometrije koliko je potrebno za rezoluciju te stranice.

  2. Nanite-ov software rasterizer je veoma efikasan za male trouglove, koji su cesti u shadow map renderovanju (jer se daleki objekti projiciraju na male povrsine u light space).

  3. Nema CPU culling bottleneck-a. Nanite radi culling na GPU-u, sto eliminise klasicni CPU bottleneck pri renderovanju hiljada objekata u shadow mape.

Bez Nanite-a, VSM bi i dalje radio, ali bi bio manje efikasan -- morao bi da koristi tradicionalni mesh rendering pipeline sa CPU culling-om.

Performansne karakteristike

VSM menja performansni profil senki:

Aspekt CSM VSM
GPU geometrijski rad Cela scena x broj kaskada, svaki frejm Samo invalidated stranice
Memorija Fiksna (npr. 4 * 2048^2) Varijabilna, zavisi od scene (tipicno 100-300 MB)
Kvalitet blizu kamere Ogranien brojem kaskada Ekstremno visok (16K efektivna rezolucija)
Kvalitet u daljini Ogranicen Takodje visok (automatski clipmap nivoi)
Lokalne svetlosti Zasebna shadow mapa po svetlu VSM po svetlu, sa kesiranjem
Cena prvog frejma Standardna Visa (mora da se renderuje sve)
Cena steadystate Konstantna (svaki frejm isto) Niza (samo promene se rerenderuju)
Skaliranje sa Nanite Lose (vise poly = sporije) Dobro (Nanite auto-LOD)

Tipicna GPU cena VSM-a u UE5:

Za srednju outdoor scenu sa directional light-om:

Za poredjenje, CSM sa 4 kaskade u istoj sceni: 2-4 ms konstantno, svaki frejm.

VSM podesavanja u UE5

VSM se aktivira u Project Settings > Engine > Rendering > Shadow:

Na svakom svetlu:

Ogranicenja i zamke

VSM nije savrsen:

  1. Memorijska potrosnja moze da bude visoka za scene sa mnogo svetlova. Svako svetlo dobija svoj VSM, i svaki zahteva memoriju za kesirane stranice.

  2. Latency pri naglim promenama. Kada se kamera naglo pomeri ili kada mnogo objekata odjednom promeni stanje, veliki broj stranica se invalidira i mora se rerenderovati. Ovo moze dovesti do frame spike-ova.

  3. Non-Nanite geometrija (skeletal meshes, particles, foliage sa WPO) ne uziva iste prednosti kao Nanite geometrija u VSM renderovanju. Za ovu geometriju, VSM mora da koristi tradicionalni rasterization pipeline.

  4. Debug tezina. VSM je kompleksniji sistem od CSM-a, pa je teze dijagnostikovati probleme. UE5 nudi vizualizacione modove (Show > Visualize > Virtual Shadow Maps) koji mogu da pomognu.

Za detaljan pregled VSM implementacije, podesavanja i best practices, pogledaj Poglavlje 31 koje je u potpunosti posveceno Virtual Shadow Maps-u.


13.7 Ray-Traced senke

Koncept

Ray-traced (RT) senke pristupaju problemu senki na fundamentalno drugaciji nacin od shadow mappinga. Umesto da renderas scenu iz perspektive svetla i cuvas dubinu u teksturi, za svaku tacku na povrsini ispaljas zrak (ray) prema svetlu i proveravaas da li taj zrak pogadja neku geometriju na putu.

Za svaku tacku P na povrsini:
    Konstruisi zrak od P prema svetlu L
    if (zrak pogadja neku geometriju pre nego sto stigne do L):
        P je u senci
    else:
        P je osvetljen

Ovo je konceptualno najjednostavnija metoda za racunanje senki, i odgovara fizickom procesu -- svetlost putuje od izvora, i ako nesto stoji na putu, pravi senku. (U praksi, pratimo zrake u obrnutom smeru -- od povrsine prema svetlu -- iz razloga efikasnosti, ali rezultat je isti.)

Hardverska podrska

Do pojave RT hardvera (NVIDIA RTX serija, 2018; AMD RDNA2, 2020), ray tracing u real-time-u je bio neprakticno skup. Moderni GPU-ovi imaju RT Core (NVIDIA) ili Ray Accelerator (AMD) -- specijalizovane hardverske jedinice za brzo testiranje presecanja zraka sa geometrijom.

Ovi jezgra implementiraju BVH traversal (Bounding Volume Hierarchy) u hardveru. BVH je hijerarhijska struktura podataka koja deli geometriju scene u ugnezdene bounding box-ove, omogucavajuci brzo pronalazenje presecanja bez testiranja svakoga trougla.

UE5 podrzava hardverski ray tracing na:

Hard shadows sa RT

Za tackastu svetlost (point light, spot light), jedna tacka je izvor svetlosti. Za svaku tacku na povrsini, ispalis jedan zrak prema poziciji svetla. Ako zrak pogodi nesto -- senka. Ako ne -- osvetljeno.

Rezultat: savrseno ostre senke, sa pikselperfektnom preciznosscu. Nema aliasinga, nema shadow acne, nema peter panninga. Ivice senki su ostre i ciste.

Za directional light (sunce, gde su svi zraci paralelni), ispalis zrak u pravcu svetla. Isti princip.

Jedan zrak po pikselu daje hard shadow -- binaran rezultat bez prelaza. Ovo je jeftinije od mekih senki, ali ne izgleda potpuno realisticno jer su senke u stvarnosti skoro uvek bar malo meke.

Soft shadows sa RT

Za meke senke, izvor svetlosti vise nije tacka vec ima konacnu velicinu (disk, sfera, pravougaonik). Za svaku tacku na povrsini, ispaljas vise zraka u razlicitim pravcima prema razlicitim pozicijama na povrsini izvora svetlosti. Procenat zraka koji su blokirani odredjuje koliko je tacka u senci:

shadow = 0
for i in range(num_rays):
    random_point_on_light = sample_light_surface()
    ray = construct_ray(P, random_point_on_light)
    if (ray_hits_geometry(ray)):
        shadow += 1

shadow_factor = shadow / num_rays  // 0 = potpuno osvetljeno, 1 = potpuno u senci

Sa dovoljno zraka (16, 32, 64...), dobijas meke, fizicki korektne senke sa penumbrom koja zavisi od velicine svetla i rastojanja od blokirajuce geometrije. Ostre senke blizu kontaktne tacke, mekse dalje -- tacno kao u stvarnosti.

Problem: svaki dodatni zrak kosta. Na 1920x1080 rezoluciji sa 32 zraka po pikselu za senke, to je 1920108032 = preko 66 miliona zraka samo za senke jednog svetla. Ovo je skupo cak i sa RT hardverom.

Resenje: denoising. Umesto 32+ zraka po pikselu, ispali 1-4 zraka po pikselu (sto daje veoma suman/zrnast rezultat) i primeni pametni denoiser koji koristi informacije iz G-buffer-a (normale, dubina, motion vectors) da rekonstruise cistsliku iz sumovitog inputa. UE5 koristi ovaj pristup -- mali broj zraka + temporalni denoiser.

Prednosti RT senki

  1. Nema aliasinga. Shadow mape imaju konacnu rezoluciju i daju blokaste ivice. RT senke imaju pikselperfektnu preciznost jer se presecanje racuna matematicki tacno.

  2. Nema shadow acne. Problem samosencenja ne postoji jer se ne radi poredjenje dubine u diskretnoj teksturi.

  3. Nema peter panninga. Nema potrebe za bias-om.

  4. Korektne meke senke. Penumbra je fizicki ispravna -- zavisi od velicine svetla i geometrije scene.

  5. Skalira sa kompleksnoscu scene drugacije. Shadow map cena zavisi od broja trouglova u sceni (jer moras da ih renderujes u shadow mapu). RT cena zavisi od broja piksela * broja zraka * kompleksnosti BVH traversal-a. Za neke scene, RT moze biti jeftiniji od shadow mapa.

Mane i cena

  1. GPU cena. I dalje skuplje od shadow mapa za vecinu scenarija, posebno za meke senke koje zahtevaju vise zraka i denoising.

  2. Sum (noise) i denoising artefakti. Sa malim brojem zraka, sum je vidljiv. Denoiser moze da uvede blurriness ili da propusti fine detalje, posebno u brzo pokretnim scenama.

  3. Hardverski zahtevi. Zahteva GPU sa RT podriskom. Na starijim GPU-ovima, performanse su znacajno gore.

  4. BVH overhead. BVH struktura za celu scenu mora da se izgradi i odrzava. Za dinamicne scene sa mnogo pokretnih objekata, BVH update moze biti skup.

RT senke u UE5

UE5 nudi RT senke kao opciju per-light:

RT senke u UE5 se mogu kombinovati sa VSM -- mozes koristiti VSM za vecinu svetlova, a RT senke za specificne svetlosti gde je kvalitet senki kriticno vazan (npr. kljucna (key) svetlost u cinematicu).

Kada koristiti RT senke

Situacija Preporuka
Cinematic / filmska produkcija Da -- kvalitet je prioritet
Kljucno svetlo u important sceni Da -- kombinuj sa VSM za ostala svetla
Masa svetlova u gameplay sceni Ne -- preskupo, koristi VSM/CSM
Igrac blizu kljucnog detalja Razmotri -- moze biti opravdano za jedno svetlo
Cela scena Retko -- preskupo za sve svetlosti
Stariji/slabiji GPU Ne -- fallback na shadow mape

13.8 Contact shadows (kontakt senke)

Problem koji resavaju

Pogledaj dole, na svoje noge na podu. Primeti kako postoji intenzivna, tanka senka tacno na mestu gde djon cipele dodiruje pod. Ili pogledaj knjigu na stolu -- tamna linija senke na kontaktnoj tacki izmedju knjige i stola.

Ove senke na kontaktnim tackama su izuzetno vazne za uverljivost -- one su signal da objekat zaista dodiruje povrsinu. Ali shadow mape ih cesto ne mogu da uhvate jer su prefinne za rezoluciju shadow mape. Cak i VSM sa 16K efektivnom rezolucijom moze da propusti senke na nivou milimetara.

Contact shadows resavaju ovaj problem koriscenjem potpuno drugacijeg pristupa: screen-space ray marching.

Kako rade

Contact shadows ne koriste shadow mape niti bacaju prave zrake kroz scenu. Umesto toga, koriste podatke koji vec postoje -- depth buffer (buffer dubine) iz glavnog rendera (o kome smo detaljno govorili u Poglavlju 09).

Algoritam:

  1. Za svaki piksel na ekranu, uzmi njegovu 3D poziciju (rekonstruisanu iz depth buffer-a).
  2. Konstruisi zrak od te pozicije prema svetlu.
  3. Umesto da pratis zrak kroz 3D scenu (kao RT senke), pratsi ga kroz screen space -- korak po korak, proveravajuci depth buffer na svakom koraku.
  4. Na svakom koraku, uporedi Z poziciju zraka sa dubinom u depth buffer-u na toj XY poziciji na ekranu. Ako je zrak "ispod" povrsine zapisane u depth buffer-u, zrak je pogodio nesto -- piksel je u senci.
ray_pos = pixel_world_position
ray_dir = normalize(light_position - pixel_world_position)
step_size = small_value

for step in range(max_steps):
    ray_pos += ray_dir * step_size
    screen_pos = project_to_screen(ray_pos)
    depth_at_screen = depth_buffer.sample(screen_pos)
    
    if (ray_pos.z > depth_at_screen):
        // zrak je prosao iza neke povrsine
        // piksel je u contact shadow-u
        return shadow
    
    step_size *= step_growth  // eksponencijalni rast koraka

return no_shadow

Prednosti

  1. Izuzetno jeftino. Contact shadows su samo jedan screen-space pass koji cita depth buffer. Nema dodatnog renderovanja geometrije.

  2. Pikselperfektni za kontaktne tacke. Koriste rezoluciju ekrana, ne shadow mape, pa mogu da uhvate finese koje shadow mape propustaju.

  3. Automatski dopunjuju shadow mape. Contact shadows dodaju detalje koje shadow mape ne mogu da pruze, bez da zamenjuju shadow mape za vece senke.

  4. Nezavisne od kompleksnosti scene. Cena je fiksna -- zavisi samo od rezolucije ekrana i broja koraka, ne od broja trouglova u sceni.

Ogranicenja

  1. Ogranicen domet. Contact shadows mogu da detektuju senke samo na kratkim rastojanjima (tipicno nekoliko centimetara do desetak centimetara). Za vece senke, moraju se koristiti shadow mape ili RT.

  2. Screen-space ogranicenja. Kao i svaka screen-space tehnika, contact shadows mogu da vide samo ono sto je vidljivo na ekranu. Objekat van ekrana ne moze da baci contact shadow. Objekat koji je zaklonjen drugim objektom u screen space-u takodje ne moze da baci contact shadow u tom pravcu.

  3. Zavisnost od depth buffer-a. Kvalitet contact shadow-a zavisi od preciznosti depth buffer-a. Thin geometry ili alpha-tested povrsine mogu da daju artefakte.

Contact shadows u UE5

UE5 ima ugradjen contact shadow sistem. Ukljucuje se na svetlu:

Contact shadows se preporucuju za sva svetla u sceni -- cena je minimalna (obicno < 0.5 ms za ceo ekran), a poboljsanje kvaliteta je odmah vidljivo, posebno za objekte na tlu.


13.9 Distance Field senke

Mesh Distance Fields -- sta su

Pre nego sto objasnimo distance field senke, moramo da razumemo sta su mesh distance fields (SDF -- Signed Distance Fields).

Za svaki mesh u sceni, UE5 moze da generise 3D teksturu koja za svaku tacku u prostoru cuva rastojanje do najblize povrsine tog mesh-a. Pozitivne vrednosti znace da je tacka van mesh-a, negativne da je unutra.

SDF(P) > 0  →  tacka P je VAN mesh-a, na rastojanju SDF(P) od povrsine
SDF(P) = 0  →  tacka P je TACNO NA POVRSINI mesh-a
SDF(P) < 0  →  tacka P je UNUTAR mesh-a

Ova informacija je izuzetno korisna za mnoge tehnike, ukljucujuci senke. Mesh distance field-ovi se generisu offline (tokom importa mesh-a) i cuvaju kao 3D teksture -- tipicno rezolucije 32x32x32 do 128x128x128 voxela, zavisno od velicine i kompleksnosti mesh-a.

Kako distance field senke rade

Umesto da pracis zrak od tacke prema svetlu i testiras presecanje sa trouglovima (sto je skupo), distance field senke koriste sphere tracing kroz SDF:

  1. Pocinjes od tacke P na povrsini.
  2. Uzorkujes SDF na poziciji P. Dobijes rastojanje D do najblize povrsine.
  3. Napredis duz zraka (prema svetlu) za rastojanje D -- jer znas da je to najdalje koliko mozes da se pomeri bez da pogodis nesto.
  4. Na novoj poziciji, ponovo uzorkujes SDF, dobijes novo rastojanje, i opet napredis.
  5. Ponavljaj dok ne stignes do svetla (osvetljeno) ili dok rastojanje ne postane veoma malo (pogodio si nesto, u senci).
position = P
total_distance = 0
min_distance = LARGE_VALUE

for step in range(max_steps):
    d = SDF.sample(position)
    min_distance = min(min_distance, d)
    
    if (d < threshold):
        return IN_SHADOW  // pogodili smo nesto
    
    position += ray_direction * d
    total_distance += d
    
    if (total_distance > max_trace_distance):
        return LIT  // stigli smo dovoljno daleko, nista ne blokira

// Bonus: min_distance tokom trace-a moze da se koristi
// za aproksimaciju mekoce senke!

Meke senke "besplatno"

Najelegantnija osobina distance field senki: meke senke dolaze gotovo besplatno. Tokom sphere tracing-a, minimalno rastojanje do najblize povrsine (min_distance) je prirodna aproksimacija koliko "blizu" je zrak prosao pored neke geometrije. Sto je blize prosao, to je veca sansa da bi siri izvor svetlosti bio delimicno blokiran.

Penumbra se aproksimira kao:

shadow_factor = min(1.0, k * min_distance / total_distance)

Gde je k parametar koji kontrolise mekocu senke (veci k = mekse). Ovo je poznato kao "soft shadow" aproksimacija po radu Inigo Quilez-a i drugih.

Rezultat: distance field senke prirodno daju meke senke koje su ostre blizu kontakta i postaju mekse sa rastojanjem, slicno PCSS-u, ali sa mnogo manje compute-a.

Distance field senke u UE5

UE5 koristi distance field senke za:

  1. Movable Meshes: Dinamicni objekti koji se pomeraju mogu da koriste DF senke za brze meke senke umesto klasicnih shadow mapa.

  2. Area light shadows: Za svetlosti sa velikom povrsinom (area lights), DF senke su efikasan nacin da se dobiju realisticne meke senke.

  3. Capsule shadows za Skeletal Meshes: Varijanta DF senki gde se skeletal mesh aproksimira nizom kapsula (za svaku kost jednu), i senke se racunaju koristeci analiticki rastojanje do kapsule umesto diskretnog SDF-a. Ovo je posebno korisno za likove u igri.

Podesavanja:

Ogranicenja

  1. Aproksimativne. SDF je diskretna 3D tekstura i ne moze da uhvati svaki detalj geometrije. Tanka geometrija, detalji manji od SDF rezolucije i deformirajuci objekti (skeletal meshes) su problematicni.

  2. Memorija. Svaki mesh sa distance field-om zahteva dodatnu 3D teksturu. Za scene sa velikim brojem unikatnih mesheva, ovo moze da zauzme znacajnu kolicinu memorije (stotine MB).

  3. Samo za opaque geometrije. Prozirni (translucent) objekti ne generisu distance field-ove.

  4. Kvalitet za kompleksnu geometriju. Meshevi sa mnogo udubljenja, rupama ili tankim delovima mogu da imaju losije DF senke jer SDF ne moze da verno reprezentuje takvu geometriju.


13.10 Staticke vs dinamicke senke

Staticke senke (Baked shadows)

Staticke senke se izracunavaju unapred (offline, tokom build-a osvetljenja) i cuvaju u lightmapama. Staticko svetlo + staticki objekat = staticka senka.

Prednosti:

Mane:

Dinamicke senke

Dinamicke senke se racunaju u realnom vremenu, svaki frejm. Ovo ukljucuje sve tehnike koje smo obradili u ovom poglavlju: shadow mape, CSM, VSM, RT senke, contact shadows, DF senke.

Prednosti:

Mane:

Hibridni pristup

U praksi, vecina UE5 projekata koristi hibridni pristup:

Sa Lumen-om i VSM-om u UE5, trend se pomera prema potpuno dinamickim senkama jer VSM daje dovoljno dobar kvalitet uz razumnu cenu, eliminisuci potrebu za baked senkama u mnogim scenarijima.


13.11 Performanse senki -- budget i optimizacija

Koliko senke kostaju

Senke su jedan od najskupljih delova render pipeline-a. U tipicnoj igri, senke mogu da zauzmu 20-40% ukupnog GPU vremena. Razumevanje cene je kljucno za optimizaciju.

Tehnika Tipicna GPU cena (1080p) Komentar
CSM (4 kaskade, 2048) 2-5 ms Zavisi od broja trouglova u sceni
VSM (steady state) 0.5-2 ms Zavisi od broja invalidated stranica
VSM (worst case) 3-8 ms Mnogo pokretnih objekata ili nagla promena kamere
RT hard shadows (1 spp) 0.5-2 ms Zavisi od kompleksnosti BVH
RT soft shadows (4 spp + denoise) 2-4 ms Zavisi od broja zraka i denoiser cene
Contact shadows 0.2-0.5 ms Screen-space, fiksna cena
DF shadows (per light) 0.3-1 ms Zavisi od broja DF objekata
Baked shadows ~0 ms Vec u lightmapi, nema runtime cene

Budget za shadow-casting svetlosti

Svako svetlo koje baca senku zahteva shadow mapu (ili ekvivalent). Ovo znaci da je broj shadow-casting svetlova u sceni direktno proporcionalan ceni senki.

Pravilo palca za shadow-casting svetlosti:

Platforma Preporuceni max shadow-casting svetlova
High-end PC 8-16 dinamickih shadow svetlova
Mid-range PC 4-8
Konzole (PS5, Xbox Series X) 4-8
Mobilni 1-2

Svetla koja ne bacaju senke (Cast Shadows = false) su znacajno jeftinija -- samo dodaju osvetljenje bez dodatnog geometry pass-a.

Strategije optimizacije

1. Ogranisi shadow distance

Podesi Dynamic Shadow Distance na razumnu vrednost. Senke na rastojanju od 500+ metara su retko vidljive. Tipicno 100-200m je dovoljno za outdoor scene.

2. Smanji broj kaskada (za CSM)

Manje kaskada = manje geometry pass-ova. Eksperimentisi sa 2-3 kaskade umesto 4.

3. Koristi VSM za Nanite scene

Za scene sa mnogo geometrije, VSM sa kesiranjem je cesto jeftiniji od CSM-a.

4. Iskljuci senke za sitne/nevazne svetlosti

Fill light-ovi, ambient light-ovi, dekorativni svetlosti -- mnogi od njih ne trebaju da bacaju senke.

5. Koristi shadow caching

UE5 ima opciju kesiranja shadow mapa za svetla koja se ne menjaju. Movable light koji ne menja poziciju/rotaciju/intenzitet ne mora da rerenderuje shadow mapu svaki frejm.

6. LOD za senke

UE5 automatski koristi LOD za objekte u shadow mapama. Mozesda dodatno kontrolises ovo putem Shadow LOD Bias na mesh-ovima -- veci bias znaci da se koristi grublji LOD u shadow mapama.

7. Per-object shadow settings

Na svakom mesh-u mozes da kontrolises:

Za male objekte koji se nece videti u senkama (sitni rekviziti, mali objekti u daljini), iskljucivanje senki moze znacajno ustedeti.

8. Shadow map resolution per-light

Nije svako svetlo jednako vazno. Glavno svetlo (sunce, mesec) zasluzuje visoku rezoluciju. Sporedna svetla mogu da koriste nizu rezoluciju.


13.12 Shadow rendering za razlicite tipove svetlosti

Directional Light (sunce)

Directional light je najzahtevniji tip svetla za senke jer osvetljava celu scenu. Opcije:

Point Light

Point light osvetljava u svim pravcima. Shadow mapa mora da pokrije celu sferu oko svetla -- sto zahteva cubemap shadow map (6 strana kocke, svaka sa zasebnim renderom). Ovo je 6x skuplje od jedne shadow mape.

Spot Light

Spot light je najjednostavniji za senke jer ima definisan konusni oblik -- jedna shadow mapa sa perspektivnom projekcijom pokriva ceo konus.

Rect Light (Area Light)

Area light-ovi nemaju klasicnu shadow map podrisku jer su prostorno rasprostranjeni izvori svetlosti. Za senke od area light-ova:


13.13 Senke i providni objekti

Providni (translucent) objekti predstavljaju poseban izazov za senke:

Problem

Shadow mape cuvaju samo dubinu -- nema informacije o providnosti. Providni objekat blokira senke kao da je potpuno neprovidan. Staklo sa shadow map senkama izgleda kao da je crni panel.

Resenja u UE5

  1. Cast Shadow = false na providnim objektima: Najjednostavnije resenje. Providni objekat ne baca senku uopste.

  2. Translucency Shadow Color: UE5 podrzava obojene senke za providne objekte koristeci poseban pristup gde se boja providnog materijala koristi za modulaciju senke.

  3. Volumetric Fog shadows: Providni volumetrijski efekti (magla, dim) mogu da primaju senke kroz volumetric fog sistem.

  4. RT senke za providne objekte: Ray tracing moze korektno da handluje providnost -- zrak prolazi kroz providni objekat sa smanjenim intenzitetom umesto da bude potpuno blokiran.

Foliage (vegetacija)

Vegetacija je poseban slucaj -- listovi su cesto alpha-tested (deo teksture je potpuno providan, deo potpuno neprovidan). Za shadow mape, ovo zahteva alpha testing tokom shadow map renderovanja, sto je skuplje od obicnog depth-only renderovanja.

UE5 podrzava Masked materijale u shadow mapama, ali sa performansnom cenom. Za gustuvegetaciju, razmotri:


13.14 Napredne teme

Shadow map atlasing

Umesto da alociras zasebnu teksturu za svaku shadow mapu, koristi atlas -- jednu veliku teksturu u kojoj su sve shadow mape smestene kao regioni. Ovo smanjuje broj texture bind operacija i moze poboljsati performanse.

UE5 koristi shadow map atlasing interno za konvencionalne shadow mape.

Shadow map caching za staticke objekte

Za staticnu geometriju, shadow mapa se ne menja izmedju frejmova. UE5 moze da kesira ove shadow mape i da ih rerenderuje samo kada se svetlo ili geometrija promeni. Ovo je posebno korisno za point i spot light-ove u interior scenama gde je vecina geometrije staticna.

Far shadows (daleke senke)

Za senke izvan dometa dinamickih shadow mapa, UE5 moze da koristi far shadows -- nize rezolucije shadow mape koje pokrivaju veliku oblast. Ovo se cesto kombinuje sa CSM-om: CSM pokriva blizu i srednje rastojanje, far shadows pokrivaju daljinu.

Subsurface scattering i senke

Za materijale sa povrsinskim rasipanjem (SSS) -- koza, vosak, listovi -- senke se ponasaju drugacije. Svetlost prodire u materijal i rasipa se, sto znaci da senke nisu potpuno crne vec imaju topliju boju (posebno za kozu, gde krv daje crvenkast ton senkama). UE5-ov SSS model uzima ovo u obzir pri izracunavanju senki.

Self-shadowing za detaljne povrsine

Za povrsine sa visokim detaljima (normal maps, displacement), self-shadowing je vazan za uverljivost. Postoje specijalizovane tehnike:


13.15 Prakticni saveti za UE5

Izbor shadow metode

Za vecinu projekata u UE5, preporuceni setup je:

  1. Ukljuci Virtual Shadow Maps za sve svetlosti kao primary shadow metod
  2. Contact shadows na svim glavnim svetlima (Cost Shadow Length = 0.02-0.05)
  3. Distance Field Shadows za area light-ove
  4. RT senke selektivno, za cinematic ili kljucna svetla gde je kvalitet prioritet

Debug alati

UE5 nudi vizualizacione modove za debug senki:

Ceste greske

  1. Previse shadow-casting svetlova. Svako svetlo sa senkama kosta. Budi strog sa tim koja svetla zaista trebaju senke.

  2. Previsoka shadow rezolucija za sporedna svetla. Koristi nizu rezoluciju za svetla koja nisu fokus paznje.

  3. Shadow distance previse velika. 500m shadow distance za interior scenu je rasipanje. Podesi za svaku scenu posebno.

  4. Ignorisanje contact shadow-a. Contact shadows su skoro besplatne a znacajno poboljsavaju kvalitet. Ukljuci ih.

  5. Zaboravljanje na shadow bias. Ako vidis shadow acne, podesavaj bias pre nego sto menjas rezoluciju.

  6. Cast Shadows na svemu. Mali rekviziti (dugmad, vijci, male dekoracije) retko trebaju da bacaju senke. Iskljuci Cast Shadows za njih.


13.16 Unakrsne reference u ovoj knjizi


13.17 Tabela kljucnih pojmova

Termin Objasnjenje
Shadow Map Tekstura koja cuva dubinu scene renderovane iz perspektive svetla. Koristi se za odredjivanje da li je piksel u senci.
Shadow Acne Artefakt samosencenja gde se na osvetljenim povrsinama pojavljuju lazne senke usled diskretizacije shadow mape.
Peter Panning Artefakt gde objekat izgleda kao da lebdi iznad terena zato sto je shadow bias previsok i senka pocinje predaleko od objekta.
Shadow Bias Mali offset koji se dodaje dubini prilikom poredjenja sa shadow mapom, da bi se sprecio shadow acne.
Slope-Scale Bias Varijanta biasa koja skalira bias prema uglu izmedju povrsine i pravca svetla.
Normal Offset Bias Tehnika gde se pozicija tacke pomera duz njene normale pre testiranja senke, umesto da se pomera dubina.
PCF (Percentage Closer Filtering) Tehnika filtriranja gde se shadow mapa uzorkuje na vise pozicija, svaki uzorak se testira individualno, i rezultati se usrednjavaju za mekse ivice senki.
PCSS (Percentage Closer Soft Shadows) Prosirenje PCF-a koje varira velicinu kernela na osnovu rastojanja do blokirajuce geometrije, dajuci fizicki korektnije meke senke.
CSM (Cascade Shadow Maps) Tehnika gde se view frustum deli na vise segmenata, svaki sa zasebnom shadow mapom, dajuci visu rezoluciju bliskim objektima.
VSM (Virtual Shadow Maps) UE5 sistem koji koristi virtuelne shadow mape ekstremno visoke rezolucije (16K) podeljene na stranice od 128x128 teksela, sa kesiranjem i on-demand renderovanjem.
Clipmap Hijerarhijska struktura gde vise nivoa razlicite rezolucije pokriva razlicite oblasti, centrirano na kameru. Koristi se u VSM za directional light.
Page (Stranica) Osnovna jedinica VSM sistema -- blok od 128x128 teksela koji se nezavisno alocira, renderuje i kesira.
Invalidation (Ponistavanje) Proces kojim se kesirana VSM stranica oznacava kao zastarela i zahteva rerenderovanje, obicno zato sto se geometrija u toj oblasti promenila.
Ray-Traced Shadows Senke racunate ispucavanjem zraka od povrsine prema svetlu i proverom da li zrak pogadja geometriju. Nema aliasing, nema acne, ali skuplje od shadow mapa.
BVH (Bounding Volume Hierarchy) Hijerarhijska struktura podataka za brzo testiranje presecanja zraka sa geometrijom. Implementirana u hardveru na modernim GPU-ovima.
Contact Shadows Screen-space ray marching tehnika za fine senke na kontaktnim tackama izmedju objekata. Jeftina, dopunjuje shadow mape.
SDF (Signed Distance Field) 3D tekstura koja za svaku tacku u prostoru cuva rastojanje do najblize povrsine mesh-a. Koristi se za sphere tracing senki.
Sphere Tracing Algoritam za pracenje zraka kroz SDF gde se na svakom koraku napreduje za rastojanje do najblize povrsine. Brz i prirodno daje meke senke.
Distance Field Shadows Senke racunate koristeci sphere tracing kroz mesh distance field-ove. Efikasne, prirodno meke, ali aproksimativne.
Umbra Oblast potpune senke gde je izvor svetlosti potpuno blokiran.
Penumbra Oblast delimicne senke gde je izvor svetlosti delimicno vidljiv. Daje senkama karakteristicnu mekocu.
Hard Shadows Senke sa ostrim, definisanim ivicama. Nastaju od tackastih izvora svetlosti ili od jednog shadow ray-a.
Soft Shadows Senke sa mekim, gradijentnim ivicama. Nastaju od prosirenih izvora svetlosti. Realticnije ali skuplje za racunanje.
Shadow Swimming Artefakt gde se senke blago pomeraju (plivaju) po povrini kada se kamera krece, usled diskretizacije shadow mape.
Capsule Shadows Varijanta DF senki gde se skeletal mesh aproksimira nizom kapsula i senke se racunaju analiticki.
Far Shadows Senke nize rezolucije za daleke objekte, van dometa primarnog shadow sistema.

13.18 Reference i dalje citanje

Akademski radovi

Epic Games resursi

Knjige

Online resursi


Rezime poglavlja

Senke su fundamentalni vizuelni signal koji daje scenama prostornost, dubinu i uverljivost. Bez senki, objekti izgledaju ravno i nepovezano sa okruzenjem. U ovom poglavlju smo prosli kroz ceo spektar tehnika za racunanje senki u real-time grafici:

  1. Shadow Mapping je dominantna tehnika -- renderuj scenu iz perspektive svetla, sacuvaj dubinu, pa uporedi sa svakim pikselom. Jednostavna ali puna artefakata: shadow acne, peter panning, aliasing. Bias tehnike i PCF/PCSS filtriranje ublazavaju ove probleme.

  2. Cascade Shadow Maps (CSM) resavaju problem rezolucije za directional light delecem view frustum-a na kaskade sa zasebnim shadow mapama. Blize kaskade imaju visu efektivnu rezoluciju. Ali CSM zahteva visestruko renderovanje scene.

  3. Virtual Shadow Maps (VSM) su UE5-ov revolucionarni pristup -- virtuelne 16K shadow mape podeljene na stranice, sa on-demand renderovanjem i kesiranjem. Integrisane sa Nanite-om za maksimalnu efikasnost. Ovo je preporuceni shadow metod za vecinu UE5 projekata.

  4. Ray-traced senke daju najkvalitetnije rezultate -- nema aliasinga, nema acne, fizicki korektne meke senke. Ali su skuplje i zahtevaju RT hardver.

  5. Contact shadows su jeftina screen-space tehnika koja dopunjuje shadow mape finim senkama na kontaktnim tackama.

  6. Distance field senke koriste SDF za brze meke senke, posebno korisne za area light-ove i pokretne objekte.

  7. Performanse su kriticne -- senke mogu da zauzmu 20-40% GPU vremena. Pametan izbor tehnika, ogranicavanje shadow distance-a, shadow caching, i kontrola broja shadow-casting svetlova su kljucni za odrzavanje frame rate-a.

U sledecem poglavlju prelazimo na novu temu, ali znanje o senkama ce ti biti potrebno kroz celu knjigu -- posebno u Poglavlju 30 (Nanite) i Poglavlju 31 (Virtual Shadow Maps u dubinu), gde cemo videti kako ovi sistemi rade zajedno da bi pruzili senke visokog kvaliteta uz razumnu performansnu cenu.