Poglavlje 15: Post-Processing
"Kada 3D renderovanje završi svoj posao -- geometrija je transformisana, pikseli su osvetljeni, senke su izračunate -- slika još uvek nije gotova. Ono što sledi je čitav novi pipeline obrade, ali ovaj put ne radimo sa 3D svetom. Radimo sa 2D slikom. I u toj 2D obradi leži razlika između 'tehničke slike' i 'finalne slike koja izgleda kao film'."
Sadržaj poglavlja
- Šta je post-processing?
- Bloom -- sjaj svetlih oblasti
- Tone mapping -- iz HDR u LDR
- Exposure i auto-exposure
- Motion blur
- Depth of Field (DOF)
- Chromatic Aberration
- Screen-Space Ambient Occlusion (SSAO, HBAO, GTAO)
- Screen-Space Reflections (SSR)
- Anti-aliasing -- detaljna analiza
- Redosled post-processing prolaza u UE5
- Rezime ključnih pojmova
- Dodatna literatura i linkovi
Uvod
U poglavlju 07 prošli smo kroz kompletan render pipeline -- od application stage-a na CPU-u, preko vertex i pixel shader-a, do konačnog upisivanja u framebuffer. Na kraju tog procesa dobijamo sliku: svaki piksel ima boju izračunatu na osnovu geometrije, materijala, osvetljenja, i senki. Ali ta slika, u tom sirovom obliku, najčešće izgleda "sterilno". Tehnički korektna, ali bez duše.
Pogledajte bilo koji savremeni film ili AAA igru. Slika ima karakter: svetle oblasti blago "krvare" u okolinu (bloom), boje su tople i filmske (tone mapping), delovi slike su blago zamućeni simulirajući fokus kamere (depth of field), brzi pokreti ostavljaju trag (motion blur). Ovi efekti ne dolaze iz 3D renderovanja -- oni se dodaju nakon njega, u fazi koju zovemo post-processing.
Ovo poglavlje je posvećeno toj fazi. Proći ćemo kroz sve glavne post-processing efekte, objasniti kako rade ispod haube, zašto postoje, koliko koštaju u smislu performansi, i kako ih Unreal Engine 5 implementira. Za neke od ovih tehnika (poput SSAO i SSR) ćemo videti da su na granici između "klasičnog post-processinga" i "screen-space tehnika renderovanja" -- ali ih svrstavamo ovde jer sve operišu nad 2D podacima nakon što je 3D renderovanje završeno.
Ako ste pročitali poglavlje 05 o teksturama i render target-ima, ovde ćete videti koliko su render target-i kritični za post-processing -- gotovo svaki efekat čita iz jednog RT-a i piše u drugi. Ako niste -- ne brinite, objašnjavaćemo kontekst gde je potrebno.
Hajde da počnemo.
15.1 Šta je post-processing?
Definicija
Post-processing (ili post-process, post-FX, post-obrada) je skup vizuelnih efekata koji se primenjuju na renderovanu sliku nakon što je 3D renderovanje završeno. Umesto da radi sa 3D geometrijom, verteksima i trouglovima, post-processing radi sa 2D screen-space podacima -- pikselima koji su već izračunati i leže u framebuffer-u (ili međubaferima).
Svaki post-processing efekat je tipično implementiran kao full-screen pixel shader pass -- shader koji se izvršava za svaki piksel na ekranu. Taj shader čita podatke iz jednog ili više render target-a (ulaz), primenjuje neku transformaciju, i upisuje rezultat u drugi render target (izlaz). Naredni efekat zatim čita iz tog novog RT-a, obrađuje ga, i piše u sledeći -- i tako dalje, dok ne dobijemo finalnu sliku.
Koncept ping-pong buffera
Većina post-processing pipeline-a koristi tehniku poznatu kao ping-pong rendering. Princip je jednostavan:
- Imate dva render target-a: RT_A i RT_B
- Originalna slika leži u RT_A
- Efekat 1 čita iz RT_A, piše u RT_B
- Efekat 2 čita iz RT_B, piše u RT_A
- Efekat 3 čita iz RT_A, piše u RT_B
- I tako naizmenično...
Zašto? Zato što GPU ne može istovremeno čitati iz i pisati u isti RT (ili preciznije, može u nekim slučajevima sa posebnim mehanizmima, ali je to opasan teren pun race condition-a). Ping-pong tehnika elegantno rešava ovaj problem. U praksi, moderni engine-i poput UE5 koriste sofisticiraniji sistem sa više RT-a i eksplicitnim grafom zavisnosti (Render Dependency Graph ili RDG), ali konceptualno je princip isti.
Šta sve post-processing koristi kao ulaz?
Post-processing efekti ne čitaju samo "boju piksela". Tokom 3D renderovanja, engine generiše nekoliko "međuproizvoda" koji se čuvaju u posebnim render target-ima. Ovi međuproizvodi, zajedno poznati kao G-Buffer (Geometry Buffer) u deferred rendering-u, sadrže:
| Buffer | Sadržaj | Ko ga koristi |
|---|---|---|
| Scene Color | HDR boja piksela (RGB + alpha) | Bloom, tone mapping, chromatic aberration |
| Scene Depth | Dubina svakog piksela (rastojanje od kamere) | DOF, SSAO, SSR, fog |
| Velocity Buffer | 2D vektor pomeranja piksela između frejmova | Motion blur, TAA |
| Normal Buffer | Normale površine u world ili view space | SSAO, SSR |
| Stencil Buffer | Celobrojne oznake za maskiranje | Custom stencil efekti |
Svaki od ovih buffer-a je zapravo render target -- tekstura u VRAM-u. Ako ste čitali poglavlje 05, setićete se da render target nije ništa drugo nego tekstura u koju GPU piše umesto da je čita. Post-processing pipeline ti svi render target-i postaju ulazi.
Zašto je redosled bitan?
Post-processing efekti se primenjuju u tačno određenom redosledu, i taj redosled drastično utiče na krajnji rezultat. Na primer:
- Ako primenite tone mapping pre bloom-a, bloom radi na LDR vrednostima i izgleda drugačije (slabije, manje ubedljivo) nego ako ga primenite na HDR sliku pre tone mappinga.
- Ako primenite anti-aliasing pre chromatic aberration-a, AA ne može da popravi artefakte koje aberration uvodi.
UE5 ima unapred definisan redosled post-processing prolaza, optimizovan za vizuelni kvalitet i performanse. O tom redosledu detaljno govorimo na kraju poglavlja (sekcija 15.11).
Post-processing i performanse
Svaki post-process efekat ima svoju cenu. Pošto su ovo full-screen shader pass-evi, njihova cena je proporcionalna rezoluciji ekrana. Na 1080p (1920×1080), svaki pass procesira oko 2 miliona piksela. Na 4K (3840×2160), to je preko 8 miliona piksela -- četiri puta više. Ovo je razlog zašto su post-processing efekti značajno skuplji na višim rezolucijama.
Neki efekti (poput prostog tone mapping-a) su izuzetno jeftini -- jedan ALU-intenzivni pass bez složenog sampleovanja. Drugi (poput bokeh DOF-a ili SSAO-a) su veoma skupi jer zahtevaju mnogo texture sample-ova za svaki piksel.
Generalna preporuka: na svakoj ciljnoj platformi, merite svaki post-process efekat individualno sa GPU profiler-om. Isključite sve efekte, pa ih uključujte jedan po jedan i beležite koliko milisekundi svaki dodaje. Ovo vam daje jasnu sliku cene svakog efekta i pomaže pri donošenju odluka o tome šta je vredno truda a šta nije.
15.2 Bloom -- sjaj svetlih oblasti
Šta je bloom?
Bloom je post-processing efekat koji simulira pojavu kada svetli objekti "krvare" svetlošću u okolne piksele. U stvarnom svetu, ovo se dešava iz dva razloga:
-
Difuzija svetlosti u oku: Svetlost koja ulazi u ljudsko oko ne pogađa retinu savršeno fokusirana. Deo svetlosti se rasejava u vitrealnom telu i samoj retini, stvarajući sjaj oko jakih izvora svetlosti.
-
Difuzija u objektivu kamere: Objektivi kamera imaju nesavršenosti -- ogrebotine, prašina, unutrašnje refleksije -- koje uzrokuju rasipanje svetlosti. Ovo je razlog zašto na fotografijama sunce ili ulična svetla imaju "halo" oko sebe.
Bloom je jedan od najprepoznatljivijih post-processing efekata i, kada je umeren, dramatično doprinosi "filmskom" izgledu slike. Kada je preteran -- dobijate onu slavnu estetiku ranih 2000-tih gde je sve izgledalo kao da je namazano vazelinom.
Kako bloom radi: korak po korak
Implementacija bloom-a je konceptualno jednostavna, ali se sastoji od nekoliko koraka:
Korak 1: Bright pass (izdvajanje svetlih piksela)
Prvi korak je identifikacija piksela koji su dovoljno svetli da bi "krvareili". Ovo se radi pomoću threshold-a (praga):
// Pseudo-HLSL za bright pass
float3 color = SceneColorTexture.Sample(sampler, uv).rgb;
float brightness = dot(color, float3(0.2126, 0.7152, 0.0722)); // luminance
float contribution = max(0, brightness - BloomThreshold);
float3 bloomColor = color * (contribution / max(brightness, 0.001));
Ovaj shader izračunava luminansu (percipiranu osvetljenost) svakog piksela, i propušta samo one čija luminansa prelazi definisani prag. Vrednosti ispod praga postaju crne (ne doprinose bloom-u), a vrednosti iznad praga zadržavaju svoju boju, ali skaliranu proporcijalno tome koliko prelaze prag.
Rezultat ovog koraka je render target koji sadrži samo svetle oblasti scene -- sve ostalo je crno. Ovo se često naziva bright pass texture ili bloom threshold texture.
U praksi, mnogi engine-i (uključujući UE5) koriste mekši prelaz umesto oštrog praga. Umesto max(0, brightness - threshold), koriste krivulju koja blago prelazi iz nule u punu vrednost, što sprečava vizualne artefakte na granici praga.
Korak 2: Downsampling i Blur
Sada imamo teksturu sa svetlim oblastima. Da bismo simulirali rasipanje svetlosti, moramo je zamutiti (blur). Ali zamutiti full-resolution teksturu je skupo -- Gaussian blur sa kernel-om od, recimo, 31×31 zahteva 961 texture sample po pikselu!
Rešenje je multi-pass blur sa downsampling-om:
- Smanjite bright pass teksturu na 1/2 rezolucije (half-res)
- Primenite blur na half-res
- Smanjite na 1/4 rezolucije (quarter-res)
- Primenite blur na quarter-res
- Nastavite sa 1/8, 1/16, 1/32...
Svaki nivo ima sve manji broj piksela (jeftiniji blur) i sve veći efektivni radius zamućenja (jer je piksel na 1/32 rezolucije ekvivalentan regionu od 32×32 piksela na punoj rezoluciji). Na kraju se svi nivoi kombinuju nazad (upsampling) u jednu blur teksturu pune rezolucije.
Ova tehnika se zove multi-resolution bloom ili mip chain bloom. UE5 koristi upravo ovaj pristup za svoj "Standard Bloom" režim, sa tipično 5-6 nivoa downsamplinga.
Gaussian Blur vs Dual Kawase Blur
Za sam blur na svakom nivou, postoje dve dominantne tehnike:
Gaussian blur je klasičan pristup. Koristi Gaussian kernel (zvonolika distribucija) za ponderisano sampleovanje okolnih piksela. U praksi se implementira kao separable filter -- umesto 2D kernel-a (N×N sampleova), radimo dva 1D pass-a: horizontalni blur pa vertikalni blur. Ovo smanjuje kompleksnost sa O(N²) na O(2N). Za kernel od 15 piksela, to je 30 sample-ova umesto 225.
Originalni pass: N×N = 225 sample-ova po pikselu (za kernel 15)
Separable pass: N + N = 30 sample-ova po pikselu (horizontalno + vertikalno)
Dual Kawase blur (poznat i kao Kawase blur, predložen od strane Masaki Kawasea) je modernija alternativa. Umesto eksplicitnog Gaussian kernel-a, koristi seriju manjih blur pass-ova sa specifičnim offset-ima koji, kada se akumuliraju, aproksimiraju Gaussian distribuciju. Prednost: manji broj texture sample-ova za sličan rezultat. Dual varijanta koristi "downsample" pass koji sampleuje 4 pozicije sa offsetom i "upsample" pass koji sampleuje 8 pozicija. Ovo je izuzetno efikasno na modernom hardveru.
Korak 3: Composite (mešanje sa originalnom slikom)
Konačno, zamućena bloom tekstura se aditivno meša sa originalnom scenom:
float3 finalColor = sceneColor + bloomTexture * BloomIntensity;
Primetite da je ovo aditivno mešanje (dodavanje), ne alfa blending. Svetli pikseli postaju još svetliji, a tamni pikseli (gde je bloom crn ili blizu nule) ostaju nepromenjeni. Parametar BloomIntensity kontroliše koliko je bloom jak.
UE5: Standard Bloom vs Convolution Bloom
Unreal Engine 5 nudi dva režima bloom-a:
Standard Bloom
Ovo je opisani multi-pass pristup sa downsampling + blur + upsampling. Brz, efikasan, i vizuelno sasvim pristojan za većinu situacija. UE5 koristi 6 nivoa (mip-ova) sa zasebnim intenzitetima za svaki, što daje artist-ima preciznu kontrolu nad "veličinom" i "oblikom" sjaja.
Parametri u UE5:
- Bloom Intensity: Ukupna jačina efekta (0 = isključen)
- Bloom Threshold: Minimalna luminansa za bloom doprinos
- Bloom Size: Kontroliše odnos između mip nivoa (veći = širi sjaj)
- Bloom #1 - #6 Size i Tint: Individualna kontrola za svaki mip nivo
Convolution Bloom
Convolution bloom je fizički preciznija, ali skuplja alternativa. Umesto multi-pass Gaussian blur-a, koristi 2D convolution (konvoluciju) sa prilagođenim kernel-om (poznatim kao "kernel texture" ili "bokeh texture").
Šta ovo znači u praksi? Možete da napravite teksturu koja definiše oblik rasipanja svetlosti. Na primer:
- Kružni kernel za simulaciju klasičnog camera bloom-a
- Kernel sa zracima za "starburst" efekat (onaj tipičan za anamorfičke objektive)
- Hexagonalni kernel za simulaciju specifičnog tipa sočiva
- Bilo koji prilagođeni oblik koji želite
Convolution bloom se matematički izračunava pomoću FFT (Fast Fourier Transform): scena se transformiše u frekventni domen, pomnoži sa kernel-om u frekventnom domenu, pa se rezultat vrati u prostorni domen inverznom FFT-om. Ovo je znatno skuplje od standardnog bloom-a, ali daje vizuelno superioran rezultat za filmski rad.
Standard Bloom: ~0.3-0.5 ms na 1080p (tipično)
Convolution Bloom: ~1.0-2.0 ms na 1080p (zavisi od kernel veličine)
Preporuka: Za igre u realnom vremenu, standard bloom je skoro uvek pravi izbor. Convolution bloom rezervišite za cinematice, filmski rad, ili platforme gde imate viška GPU budžeta.
Česte greške sa bloom-om
-
Previše bloom-a: Ako intenzitet postavite previsoko, scena izgleda "isprana" i gubi kontrast. Bloom treba da bude suptilan -- primetite ga tek kad ga isključite.
-
Prenizak threshold: Ako je prag prenizak, skoro svaki piksel doprinosi bloom-u, što daje jednolični sjaj preko cele slike umesto fokusiranog sjaja oko svetlih izvora.
-
Bloom na LDR slici: Bloom ima smisla samo na HDR slici, gde svetli pikseli zaista imaju mnogo veće vrednosti od tamnijih. Na LDR slici (vrednosti 0-1), razlika između "svetlog" i "tamnog" je premala da bi bloom imao ubedljiv efekat.
15.3 Tone Mapping -- iz HDR u LDR
Problem: scena živi u HDR, ekran živi u LDR
Ovo je jedan od fundamentalnih problema renderovanja, i da bismo ga razumeli, moramo se vratiti na koncept dinamičkog opsega (dynamic range).
U stvarnom svetu, osvetljenost objekata varira enormno:
| Scena | Približna luminansa (cd/m²) |
|---|---|
| Mesečina na tlu | 0.001 |
| Soba sa veštačkim svetlom | 50 - 500 |
| Oblačan dan napolju | 1,000 - 5,000 |
| Sunčan dan | 10,000 - 100,000 |
| Direktan pogled u sunce | ~1,600,000,000 |
Razlika od najslabije do najjače scene je preko trilion puta. Čak i u jednoj sceni -- recimo, soba sa prozorom -- imate ogromnu razliku između senke u uglu sobe i neba vidljivog kroz prozor.
Tokom renderovanja, UE5 računa osvetljenost u HDR (High Dynamic Range) formatu. Boje piksela nisu ograničene na opseg 0-1. Svetao piksel može imati vrednost 10, 100, pa čak i 1000. Ovo je neophodno za fizički korektno izračunavanje -- bloom, refleksije, i mnogi drugi efekti zahtevaju da svetli objekti zaista budu mnogo svetliji od tamnijih.
Ali vaš monitor ne može prikazati vrednost 100. Tipičan SDR (Standard Dynamic Range) monitor prikazuje boje u opsegu od 0 do 1 (ili 0 do 255 u 8-bitnom formatu). Čak i HDR monitori imaju ograničen opseg, mada mnogo širi od SDR-a.
Tone mapping je proces konvertovanja HDR vrednosti u opseg koji displej može prikazati, na način koji čuva što više vizuelnih informacija i izgleda prijatno oku.
Naivni pristup: clamp
Najjednostavniji "tone mapping" bi bio da jednostavno ograničimo vrednosti:
float3 output = clamp(sceneColor, 0.0, 1.0);
Rezultat? Katastrofa. Svaki piksel sa vrednošću iznad 1 postaje beo. Nebo, sunce, refleksije -- sve postaje jedna monotona bela masa. Gubite sve detalje u svetlim oblastima. Ovo se zove clipping i to je upravo ono što tone mapping pokušava da izbegne.
Reinhard tone mapping
Jedan od prvih široko korišćenih tone mapping operatora je Reinhard (Erik Reinhard, 2002):
float3 output = sceneColor / (1.0 + sceneColor);
Ova jednostavna formula ima elegantno svojstvo: vrednosti bliske nuli ostaju skoro nepromenjene (jer x / (1 + x) ≈ x za male x), dok se velike vrednosti kompresuju prema 1 ali nikada ne dostižu 1 (jer x / (1 + x) < 1 za svako pozitivno x).
Problem sa Reinhard-om: tamne oblasti su tačne, ali svetle oblasti gube kontrast i zasićenost. Slika izgleda "ravno" -- nema onog filmskog kvaliteta koji očekujemo.
Filmic tone mapping
Filmska industrija je decenijama koristila hemijske procese koji su prirodno kompresovali dinamički opseg scene na film. Ta karakteristična S-krivulja -- blago kompresovane senke, linearan srednji opseg, glatko roll-off u svetlim oblastima -- je ono što naše oči prepoznaju kao "filmski izgled".
Filmic tone mapping operatori pokušavaju da repliciraju ovu S-krivulju. Najpoznatiji je Hable/Uncharted 2 tone mapper (John Hable, 2010), korišćen u igri Uncharted 2:
float3 Uncharted2Tonemap(float3 x)
{
float A = 0.15; // Shoulder Strength
float B = 0.50; // Linear Strength
float C = 0.10; // Linear Angle
float D = 0.20; // Toe Strength
float E = 0.02; // Toe Numerator
float F = 0.30; // Toe Denominator
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}
Ova krivulja ima:
- Toe region (donji deo): blaga kompresija senki, daje mekoću tamnim oblastima
- Linear region (srednji deo): skoro linearan prolaz, čuva kontrast
- Shoulder region (gornji deo): glatka kompresija svetlih oblasti, sprečava clipping
ACES (Academy Color Encoding System)
ACES je industrijski standard za upravljanje bojama u filmskoj i televizijskoj produkciji, razvijen od strane Academy of Motion Picture Arts and Sciences (ista organizacija koja dodeljuje Oscare). Unreal Engine 5 koristi ACES-bazirani tone mapping kao podrazumevani.
ACES nije samo tone mapping operator -- to je kompletan sistem za upravljanje bojama koji obuhvata:
- Input Device Transform (IDT): Konvertuje boje sa specifičnog uređaja (kamere, rendera) u ACES radni prostor
- Reference Rendering Transform (RRT): Filmic tone mapping -- S-krivulja koja simulira filmski "look"
- Output Device Transform (ODT): Konvertuje iz ACES prostora u prostor specifičnog displeja (sRGB monitor, Rec.709 TV, DCI-P3 projektor, itd.)
Kombinacija RRT + ODT se zove Output Transform i to je ono što UE5 primenjuje kao tone mapping.
ACES tone mapping daje karakterističan "filmski" izgled:
- Tople senke (blagi crvenkasti/narandžasti ton u tamnim oblastima)
- Hladniji highlights
- Prijatna zasićenost boja u srednjem opsegu
- Glatki prelaz u svetlim oblastima bez oštrog clipping-a
HDR scene color → ACES Input Transform → ACES RRT → ACES ODT → LDR display color
GT Tone Mapper u UE5
Pored ACES-a, UE5 je u novijim verzijama uveo i GT (Gran Turismo) tone mapper, inspirisan radom Hajime Uchimura-e za igru Gran Turismo Sport. GT tone mapper nudi nekoliko prednosti:
- Manje desaturacije u svetlim oblastima: ACES ima tendenciju da desaturiše (izbeljuje) veoma svetle boje. GT mapper bolje čuva zasićenost.
- Konzistentniji kontrast: Održava vizuelni kontrast čak i pri visokim vrednostima ekspozicije.
- Parametrizovana krivulja: Omogućava precizno podešavanje oblika tone mapping krivulje.
U praksi, većina projekata u UE5 koristi ACES jer je to industrijski standard i većina artista je navikla na njegov izgled. GT mapper je alternativa za projekte koji žele drugačiji vizuelni stil ili imaju specifične zahteve oko očuvanja zasićenosti.
Kako tone mapping menja "look" slike
Tone mapping je možda najvažniji faktor u definisanju vizuelnog identiteta igre ili filma. Ista 3D scena sa istim osvetljenjem može izgledati potpuno drugačije samo promenom tone mapping operatora:
| Operator | Karakteristika |
|---|---|
| Linear clamp | Oštar, "sirov", gubi detalje u svetlim oblastima |
| Reinhard | Mekan, ali "ravan" -- nedostaje kontrast |
| Hable/Filmic | Topao, filmski, dobar kontrast |
| ACES | Bogat, filmski, lagana desaturacija svetlih oblasti |
| GT | Sličan ACES-u ali čuva zasićenost bolje |
Važno je razumeti: tone mapping nije "ispravljanje" slike -- to je kreativna odluka. Različiti tone mapperi daju različite emocije i atmosfere. ACES daje osećaj "holivudskog filma", dok linearniji mapperi mogu dati osećaj "dokumentarca" ili "realizma".
Za dublje razumevanje teorije boja i color space-ova koji su usko povezani sa tone mapping-om, pogledajte poglavlje 16 posvećeno nauci o boji (color science).
15.4 Exposure i Auto-Exposure
Šta je exposure?
Exposure (ekspozicija) kontroliše ukupnu osvetljenost slike. U fotografiji, ekspozicija je kontrolisana fizičkim parametrima kamere: koliko svetlosti dopustite da upadne na senzor, i koliko dugo. U renderovanju, ekspozicija je jednostavno množilac koji se primenjuje na HDR sliku pre tone mappinga:
float3 exposedColor = sceneColor * pow(2.0, ExposureValue);
// ili jednostavnije:
float3 exposedColor = sceneColor * ExposureMultiplier;
Zašto nam treba exposure? Zato što ton mapping krivulja očekuje ulazne vrednosti u određenom opsegu. Ako su scene values previsoke (prepuna sunca), tone mapper će sve kompresovati i slika će biti ispirano bela. Ako su preniske (noćna scena), tone mapper će sve ostaviti previše tamno. Exposure služi da "pomeri" vrednosti u optimalan opseg za tone mapper.
Analogija sa kamerom
U fotografiji, ekspozicija je kontrolisana sa tri parametra:
-
Aperture (otvor blende, f-stop): Koliko je otvoren objektiv. Veći otvor (manji f-broj, npr. f/1.4) propušta više svetlosti. Manji otvor (veći f-broj, npr. f/16) propušta manje.
-
Shutter speed (brzina zatvarača): Koliko dugo je senzor izložen svetlosti. Duža ekspozicija (npr. 1/30s) propušta više svetlosti. Kraća (npr. 1/1000s) propušta manje.
-
ISO (osetljivost senzora): Koliko je senzor osetljiv na svetlost. Viši ISO (npr. 3200) pojačava signal ali dodaje šum. Niži ISO (npr. 100) daje čistiju sliku ali zahteva više svetlosti.
Ova tri parametra se kombinuju u jednu vrednost poznatu kao EV100 (Exposure Value pri ISO 100):
EV100 = log2(N² / t) - log2(ISO / 100)
gde je N f-broj, t je brzina zatvarača u sekundama, i ISO je osetljivost.
UE5 podržava rad sa ovim fizičkim parametrima kamere. U Post Process Volume-u ili u CineCamera Actor-u, možete postaviti aperture, shutter speed, i ISO, i engine će izračunati ekspoziciju na isti način kao prava kamera. Ovo je posebno korisno za filmski rad i za postizanje realističnog izgleda.
Manual Exposure
Manualna ekspozicija znači da vi, kao developer ili artist, ručno postavljate ekspoziciju na fiksnu vrednost. Scena je uvek prikazana sa istom osvetljenošću, bez obzira na to koliko je svetla ili tamna.
Prednosti:
- Potpuna kontrola nad izgledom svake scene
- Konzistentnost -- nema neočekivanih promena osvetljenosti
- Idealno za kontrolisana okruženja (enterijeri, predefinisane scene)
Mane:
- Zahteva ručno podešavanje za svaku scenu
- Ako igrač prelazi iz tamne u svetlu oblast, morate ručno rešiti tranziciju
U UE5, manualna ekspozicija se postavlja u Post Process Volume-u:
Metering Mode: ManualExposure Compensation: EV offset (pozitivno = svetlije, negativno = tamnije)
Auto-Exposure (Eye Adaptation)
Automatska ekspozicija simulira sposobnost ljudskog oka (i kamere) da se prilagodi promenama osvetljenosti. Kada uđete u tamnu prostoriju, vaše oči se postepeno prilagode i počnete da vidite detalje. Kada izađete napolje na sunce, privremeno ste zaslepljeni dok se oči ne prilagode. Auto-exposure simulira upravo ovaj fenomen.
Kako radi: Histogram-Based Auto-Exposure
UE5 koristi histogram-baziranu automatsku ekspoziciju, koja je sofisticiranija od prostog prosečenja luminanse:
Korak 1: Izračunavanje luminanse
Za svaki piksel scene, izračunava se luminansa:
float luminance = dot(color.rgb, float3(0.2126, 0.7152, 0.0722));
float logLuminance = log2(luminance + epsilon); // log2 za bolju distribuciju
Koristi se logaritamska skala jer ljudsko oko percipira osvetljenost logaritamski, ne linearno (duplo više svetlosti ne izgleda duplo svetlije).
Korak 2: Konstrukcija histograma
Logaritamske luminanse se grupišu u "kante" (bins) histograma. Tipično se koristi 64 ili 128 kanti raspoređenih od minimalne do maksimalne vrednosti (npr. od -8 EV do +20 EV). Histogram pokazuje distribuciju osvetljenosti u sceni -- koliko piksela je tamno, koliko je srednje, koliko je svetlo.
Korak 3: Određivanje ciljne ekspozicije
Engine ne koristi prosek cele slike jer bi svetle oblasti (nebo, sunce) prekomerno uticale na ekspoziciju. Umesto toga, koristi percentile histograma:
Low Percent = 80% (ignoriši najnižih 80% piksela po luminansi)
High Percent = 98% (ignoriši najviših 2% piksela po luminansi)
Ovo znači: "uzmi u obzir samo piksele čija je luminansa između 80. i 98. percentila". Time se ignorišu i tamne senke (koje bi dovele do preeksponiranja) i direktni izvori svetlosti (koji bi doveli do podeksponiranja). Rezultat je ekspozicija optimizovana za "sredinu" scene -- ono na šta igrač zapravo gleda.
Korak 4: Prilagođavanje (Adaptation)
Ekspozicija se ne menja instantno. Engine postepeno prilagođava ekspoziciju koristeći exponential smoothing:
currentExposure = lerp(currentExposure, targetExposure, 1.0 - exp(-deltaTime / adaptationSpeed));
adaptationSpeed kontroliše koliko brzo se ekspozicija menja. U UE5 imate dva odvojena parametra:
- Speed Up: Koliko brzo se ekspozicija prilagođava pri prelasku iz tamnog u svetlo (tipično brže, 2-3 sekunde)
- Speed Down: Koliko brzo se ekspozicija prilagođava pri prelasku iz svetlog u tamno (tipično sporije, 5-10 sekundi)
Razlog za asimetriju: u stvarnom životu, oči se brže prilagode svetlosti (pupila se brzo suzi) nego tami (pupila se sporo širi, plus hemijski procesi u retini).
Opseg auto-exposure-a
UE5 dozvoljava postavljanje minimalnog i maksimalnog EV za auto-exposure:
- Min EV: Koliko tamna može biti scena. Sprečava engine da "prekomerno pojača" tamne scene.
- Max EV: Koliko svetla može biti scena. Sprečava engine da "prekomerno smanji" svetle scene.
Ovo je kritično za kontrolu. Bez ograničenja, auto-exposure bi mogao da:
- U potpuno tamnoj prostoriji pojača sliku toliko da šum postane vidljiv
- U veoma svetloj sceni smanji ekspoziciju toliko da sve izgleda sivo
Praktični saveti za auto-exposure
-
Koristite Post Process Volume-e za svaku oblast: Enterijer i eksterijer zahtevaju različite EV opsege. Stavite PPC Volume na svaku zonu i podesite min/max EV za svaku.
-
Testirajte tranzicije: Pokrenite igru i fizički prođite iz svetle u tamnu oblast. Da li je tranzicija glatka? Da li je brza dovoljno? Da li se stabilizuje na dobru vrednost?
-
Low i High Percent: Podrazumevane vrednosti (80% / 98%) rade dobro za većinu scena. Ako imate scenu sa velikim područjem neba, možda ćete hteti da podignete High Percent da bi nebo manje uticalo na ekspoziciju.
-
Exposure Compensation: Čak i sa auto-exposure-om, možete dodati fiksan offset (EV compensation). Ovo je korisno ako auto-exposure daje konzistentno presvetlu ili pretamnu sliku za vaš ukus.
15.5 Motion Blur
Zašto motion blur?
Motion blur (zamućenje pokreta) je efekat koji simulira pojavu kada se objekti (ili kamera) kreću tokom ekspozicije. U pravoj kameri, zatvarač je otvoren tokom trajanja jednog frejma (npr. 1/24 sekunde za film). Sve što se pomeri tokom tog vremena biva "razmazano" na filmu/senzoru.
Zašto bismo hteli da simuliramo ovu pojavu u renderovanju, gde svaki frejm daje savršeno oštru sliku?
-
Percepcija glatkoće: Ljudski vizuelni sistem koristi motion blur kao signal za brzinu i smer kretanja. Bez njega, brzi pokret izgleda "isprekidano" (stroboskopski efekat), posebno na nižim frameRate-ovima (30 FPS). Motion blur perceptualno "popunjava" prostor između frejmova i stvara iluziju glatkijeg pokreta.
-
Filmski izgled: Motion blur je neizostavni deo filmske estetike. Film se snima na 24 FPS sa 180° shutter angle-om (zatvarač je otvoren pola vremena frejma), što daje karakterističan izgled koji gledalac podsvesno prepoznaje kao "filmski".
-
Maskiranje niskog frame rate-a: Na 30 FPS, motion blur čini pokrete manje "trzavim". Na 60+ FPS, efekat je manje potreban, ali i dalje doprinosi filmskom kvalitetu.
Tipovi motion blur-a
Camera Motion Blur
Camera motion blur simulira zamućenje celokupne slike uzrokovano pokretom kamere (translacijom ili rotacijom). Kada kamera rotira, cela slika se pomera u istom smeru, pa blur ima jedinstven pravac za sve piksele (mada intenzitet varira -- pikseli na periferiji se pomeraju više od piksela u centru pri rotaciji).
Implementacija: za svaki piksel, izračunajte koliko se ta pozicija na ekranu pomerila između prošlog i trenutnog frejma (koristeći prethodnu i trenutnu View-Projection matricu). Taj 2D vektor pomeranja definiše pravac i intenzitet blur-a.
Per-Object Motion Blur
Per-object motion blur simulira zamućenje pojedinačnih objekata koji se kreću. Dok kamera stoji mirno, ruka karaktera koja zamahuje mačem treba da bude zamućena, ali pozadina ostaje oštra.
Ovo zahteva velocity buffer (vektor brzine za svaki piksel). Tokom renderovanja geometrije, engine izračunava koliko se svaki vertex pomerio između prethodnog i trenutnog frejma, i tu informaciju upisuje u poseban render target. Rezultat je tekstura gde svaki piksel sadrži 2D vektor koji govori "ovaj piksel se pomerio za (dx, dy) piksela od prošlog frejma".
Velocity Buffer (schematski prikaz):
┌─────────────────────────────┐
│ (0,0) (0,0) (0,0) │ ← Statička pozadina
│ (0,0) (5,2) (5,2) │ ← Pokretni objekat
│ (0,0) (5,2) (5,2) │
│ (0,0) (0,0) (0,0) │ ← Statička pozadina
└─────────────────────────────┘
Kombinovani motion blur
U praksi, UE5 kombinuje oba tipa. Velocity buffer sadrži i pokret kamere i pokret objekata. Shader za motion blur čita velocity buffer i za svaki piksel sampleuje scene color duž vektora brzine, akumulirajući boje da bi stvorio efekat zamućenja.
// Pojednostavljeni motion blur shader
float2 velocity = VelocityTexture.Sample(sampler, uv).rg;
float3 result = float3(0, 0, 0);
int numSamples = 8;
for (int i = 0; i < numSamples; i++)
{
float t = (float(i) / float(numSamples - 1)) - 0.5; // -0.5 do +0.5
float2 sampleUV = uv + velocity * t;
result += SceneColor.Sample(sampler, sampleUV).rgb;
}
result /= float(numSamples);
Ovaj shader sampleuje scene color na nekoliko pozicija duž vektora brzine (pola unazad, pola unapred od trenutne pozicije) i prosečuje rezultate. Više sample-ova = glatkiji blur ali viša cena.
Performanse motion blur-a
Cena motion blur-a zavisi od:
-
Broja sample-ova: Više sample-ova = glatkiji rezultat ali više texture fetch-eva. UE5 tipično koristi 8-16 sample-ova.
-
Veličine velocity vektora: Pikseli sa velikim vektorima brzine zahtevaju sample-ove koji su šire raspoređeni, potencijalno izazivajući cache miss-eve u texture cache-u.
-
Rezolucije: Kao i svaki full-screen pass, cena je proporcionalna broju piksela.
U praksi, motion blur tipično košta 0.2-0.5 ms na modernom GPU-u na 1080p. Na 4K, može dostići 1 ms.
Kontrole u UE5
- Motion Blur Amount: Intenzitet efekta (0 = isključen, 1 = normalan)
- Max Blur Amount: Ograničava maksimalnu veličinu blur-a (sprečava preterano zamućenje)
- Target FPS: Motion blur se prilagođava target frame rate-u. Na 60 FPS, blur je upola kraći nego na 30 FPS (jer je "ekspozicija" frejma upola kraća)
- Per Object Motion Blur: Može se isključiti per-objekat za objekte gde ne želite blur
Kontroverza: da li isključiti motion blur?
Motion blur je jedan od najkontroverznijih post-processing efekata. Mnogi igrači ga isključuju jer:
- Može uzrokovati mučninu (motion sickness) kod nekih osoba
- Na visokim frame rate-ovima (120+ FPS) nije potreban i samo "mutira" sliku
- U kompetitivnim igrama, oštrina slike je prioritet
Kao developer, razmislite o tome da ponudite opciju za isključivanje. Za filmski rad i single-player igre fokusirane na vizuelni kvalitet, motion blur je izuzetno vredan alat.
15.6 Depth of Field (DOF)
Šta je Depth of Field?
Depth of Field (dubina polja, DOF) je post-processing efekat koji simulira ponašanje optičkog sočiva: objekti na određenoj udaljenosti od kamere su u fokusu (oštri), dok su objekti bliži ili dalji od te udaljenosti zamućeni. Ovaj efekat je fundamentalan za filmski izgled i za usmeravanje pažnje gledaoca.
U stvarnom svetu, DOF je posledica fizike sočiva. Svetlost sa tačke koja nije u fokusu ne konvergira u jednu tačku na senzoru, već formira disk -- taj disk se zove circle of confusion (krug konfuzije, CoC).
Circle of Confusion (CoC)
Circle of Confusion je ključni koncept za razumevanje DOF-a. Zamislite sledeće:
- Sočivo je fokusirano na rastojanje od 5 metara.
- Tačka svetlosti na 5 metara: zraci prolaze kroz sočivo i konvergiraju u jednu tačku na senzoru. → Oštar piksel.
- Tačka svetlosti na 10 metara: zraci prolaze kroz sočivo ali konvergiraju iza senzora. Na samom senzoru, umesto tačke, formiraju disk. → Zamućen piksel.
- Tačka svetlosti na 2 metra: zraci konvergiraju ispred senzora. Na senzoru, opet disk. → Zamućen piksel.
Veličina tog diska (CoC) zavisi od:
- Rastojanja objekta od fokusa: Što je objekat dalje od fokusne ravni, veći je CoC
- Aperture (otvora blende): Širi otvor (manji f-broj) = veći CoC = jače zamućenje
- Žižne daljine (focal length): Duže žižne daljine daju manji DOF (veće zamućenje)
U renderovanju, za svaki piksel izračunavamo CoC na osnovu njegovog rastojanja od kamere (iz depth buffer-a) i parametara "virtuelnog sočiva":
float depth = DepthBuffer.Sample(sampler, uv);
float coc = abs(depth - FocusDistance) * ApertureSize / depth;
coc = clamp(coc, 0, MaxBlurSize);
Piksel sa CoC = 0 je u fokusu (oštar). Piksel sa velikim CoC je van fokusa (zamućen). Predznak CoC-a može označavati da li je piksel ispred ili iza fokusne ravni.
Tri zone DOF-a
DOF deli scenu u tri zone:
-
Near DOF (prednje zamućenje): Objekti koji su bliže kameri od fokusne ravni. Ovo zamućenje se retko koristi u igrama jer je neprijatno za igranje, ali je čest filmski efekat (npr. zamućen prednji plan dok je lik u pozadini oštar).
-
In-focus zone (zona fokusa): Oblast oko fokusne ravni gde je CoC dovoljno mali da se piksel smatra oštrim. Širina ove zone zavisi od aperture-a i žižne daljine.
-
Far DOF (zadnje zamućenje): Objekti dalji od fokusne ravni. Ovo je najčešća upotreba DOF-a u igrama -- zamućena pozadina dok je lik u prvom planu oštar.
Implementacije DOF-a u UE5
UE5 nudi tri različite implementacije DOF-a, svaka sa svojim prednostima i manama:
Gaussian DOF
Najjednostavnija i najjeftinija implementacija. Za svaki piksel, primenite Gaussian blur čiji radius zavisi od veličine CoC za taj piksel.
CoC mali → blur sa malim kernel-om → blago zamućenje
CoC veliki → blur sa velikim kernel-om → jako zamućenje
Prednosti:
- Brz (tipično 0.3-0.5 ms)
- Stabilan rezultat bez artefakata
Mane:
- Nerealistično zamućenje: Gaussian blur daje "ravnomerno" zamućenje, dok prava sočiva daju karakteristične oblike bokeh-a (krugove, heksagone, itd.)
- Near DOF može imati artefakte na granicama oštrog/zamućenog regiona
Bokeh DOF
Bokeh (japanska reč za "zamućenost") se odnosi na estetski kvalitet zamućenih oblasti slike. U pravom sočivu, svaka tačka svetlosti van fokusa postaje disk oblika otvora blende -- krug za kružne blende, heksagon za šestolisnu blendu, itd.
Bokeh DOF u UE5 pokušava da replicira ovo tako što za svaki piksel koji je van fokusa generiše sprite u obliku bokeh-a, sa veličinom proporcionalnom CoC-u i bojom tog piksela.
Prednosti:
- Vizuelno veoma ubedljiv, posebno za svetle tačke (ulična svetla noću, refleksije na vodi)
- Čuva oblik bokeh-a vererno fizičkom modelu
Mane:
- Izuzetno skup: Za svaki piksel van fokusa generiše se sprite koji pokriva potencijalno veliki region ekrana. Na sceni sa mnogo zamućenog prostora, ovo može generisati milione overlapping sprite-ova.
- Performansa: može koštati 3-10+ ms na kompleksnim scenama
- UE5 je ovu implementaciju u velikoj meri zamenio Cinematic DOF-om
Cinematic DOF (DiaphragmDOF)
Ovo je moderna, preporučena implementacija DOF-a u UE5. Kombinuje kvalitet bokeh DOF-a sa performansama bliskim Gaussian DOF-u.
Cinematic DOF koristi sofisticiraniji pristup:
- Scenu deli u near i far sloj na osnovu CoC-a
- Svaki sloj se blur-uje nezavisno
- Blur koristi kernel koji aproksimira oblik blende (krug, poligon) bez eksplicitnog generisanja sprite-ova
- Koristi scatter-as-gather pristup: umesto da svaki piksel "razaspe" svoju boju (scatter), svaki piksel "prikupi" boje iz okoline sa odgovarajućim težinama (gather). Gather pristup je mnogo efikasniji na modernom GPU hardveru.
Prednosti:
- Visok vizuelni kvalitet -- blizak pravom bokeh-u
- Razumna cena (tipično 0.5-1.5 ms na 1080p)
- Podržava oblik blende (broj sečiva, rotacija)
- Dobro rukuje near/far DOF tranzicijama
Mane:
- Skuplje od Gaussian-a
- Na ekstremno velikim CoC vrednostima može pokazati artefakte
Parametri DOF-a u UE5
| Parametar | Opis |
|---|---|
| Focus Distance | Rastojanje od kamere do fokusne ravni (u cm) |
| Aperture (F-stop) | Otvor blende -- manji broj = jače zamućenje |
| Focal Length | Žižna daljina virtuelnog sočiva (u mm) |
| Sensor Size | Veličina virtuelnog senzora |
| Near Transition Region | Širina prelazne zone za near DOF |
| Far Transition Region | Širina prelazne zone za far DOF |
| Blade Count | Broj sečiva blende (utiče na oblik bokeh-a) |
| Max Bokeh Size | Ograničava maksimalnu veličinu bokeh diskova |
Praktični saveti za DOF
-
Ne preterujte: Previše DOF-a u gameplay-u može otežati percepciju okoline. Koristite ga umereno -- blago zamućenje pozadine može pomoći fokusu, ali jako zamućenje nervira igrače.
-
CineCamera Actor: Za filmske sekvence, koristite CineCamera Actor koji simulira fizičke parametre kamere (aperture, focal length, focus distance). DOF će automatski biti fizički korektan.
-
Automatic focus: UE5 može automatski fokusirati na objekat ili tačku u sceni. Za gameplay, možete fokusirati na centar ekrana ili na "aim target" igrača.
-
Performanse: Ako je DOF preskup, smanjite Max Bokeh Size. To ograničava maksimalnu veličinu zamućenja i direktno smanjuje cenu.
15.7 Chromatic Aberration
Šta je Chromatic Aberration?
Chromatic aberration (hromatska aberacija, CA) je optička pojava gde sočivo ne uspe da fokusira sve talasne dužine svetlosti na istu tačku. Rezultat je "razdvajanje boja" na ivicama objekata, posebno prema periferiji slike.
Ovo se dešava zato što indeks prelamanja stakla zavisi od talasne dužine svetlosti (fenomen poznat kao disperzija). Plava svetlost se prelama jače od crvene, pa konvergira na drugom mestu. Na senzoru kamere, ovo izgleda kao crveni/plavi rub na kontrastnim ivicama.
Implementacija
U post-processingu, chromatic aberration se implementira iznenađujuće jednostavno:
// Pojednostavljen CA shader
float2 direction = uv - float2(0.5, 0.5); // Pravac od centra ekrana
float amount = length(direction) * ChromaticAberrationIntensity;
float3 result;
result.r = SceneColor.Sample(sampler, uv + direction * amount).r;
result.g = SceneColor.Sample(sampler, uv).g;
result.b = SceneColor.Sample(sampler, uv - direction * amount).b;
Šta ovaj shader radi:
- Izračunava pravac od centra ekrana do trenutnog piksela
- Sampleuje crveni kanal sa blagim pomakom u jednom smeru
- Sampleuje zeleni kanal na originalnoj poziciji
- Sampleuje plavi kanal sa blagim pomakom u suprotnom smeru
Rezultat: piksel je sastavljen od tri boje sampleovane sa blago različitih pozicija, što simulira razdvajanje boja. Efekat je jači na periferiji (veći direction vektor) i nula u centru ekrana -- tačno kao kod pravog sočiva.
Kontrole u UE5
UE5 ima jednostavne kontrole za CA:
- Chromatic Aberration Intensity: Jačina efekta (0 = isključen, tipično 0.0-1.0)
- Chromatic Aberration Start Offset: Od koje udaljenosti od centra ekrana počinje efekat
Praktični saveti
-
Manje je više: Chromatic aberration treba da bude jedva primetan. Tipične vrednosti su 0.1-0.3. Vrednosti iznad 0.5 izgledaju agresivno i neprijatno.
-
Filmski vs gejming: U filmskom radu, blaga CA dodaje "realizam" jer sve prave kamere imaju neki stepen CA. U igrama, mnogi igrači je smatraju iritantnom i isključuju je.
-
Horror i sci-fi: Preterana CA može biti stilski izbor za horror igre ili scene sa distorzijom stvarnosti (halucinacije, oštećenje kamere, itd.).
-
Cena: Zanemarljiva -- tri texture fetch-a umesto jednog. Praktično besplatno.
15.8 Screen-Space Ambient Occlusion
Šta je Ambient Occlusion?
Pre nego što zaronimo u screen-space tehnike, hajde da ponovimo šta je ambient occlusion (AO) uopšte.
Ambient Occlusion je mera koliko je svaka tačka na površini "zaklonjena" okolnom geometrijom od ambijentalnog (indirektnog) svetla. Uglovi, pukotine, i oblasti gde se objekti dodiruju primaju manje ambijentalnog svetla jer je okolna geometrija blokira. AO kvantifikuje ovaj efekat kao skalirni faktor: 1.0 = potpuno izložen (belo), 0.0 = potpuno zaklonjen (crno).
Pogledajte bilo koji ugao u sobi. Primetite kako je spoj zida i poda tamniji nego sredina zida. To je ambient occlusion u stvarnom životu -- taj ugao prima manje indirektne svetlosti jer su zid i pod "blokiraju" velik deo hemisfere.
Kao što smo videli u poglavlju 12, globalna iluminacija automatski uključuje ambient occlusion kao nusproizvod -- tačke koje su okružene geometrijom prirodno primaju manje indirektne svetlosti. Ali GI je skupa. Screen-space AO tehnike pokušavaju da aproksimiraju ovaj efekat jeftino, koristeći samo podatke dostupne u screen space-u (pre svega depth buffer).
SSAO (Screen-Space Ambient Occlusion)
Istorija
SSAO je uveo Crytek 2007. godine za igru Crysis, i bio je revolucionaran u tom trenutku. Pre SSAO-a, AO je morao biti prebaked u teksture (što je bilo statično i ne prilagodljivo dinamičkim scenama) ili izračunat punim GI-om (preskupo za real-time).
Kako radi
Za svaki piksel na ekranu:
- Pročitaj dubinu i normalu piksela iz G-Buffer-a
- Rekonstruiši 3D poziciju piksela u view space-u koristeći dubinu i projekcionu matricu
- Generiši nasumične sample tačke u sferi (ili hemisferi) oko te pozicije
- Za svaku sample tačku, projektuj je nazad na ekran i pročitaj dubinu iz depth buffer-a na toj poziciji
- Uporedi: Ako je dubina iz depth buffer-a manja (bliža kameri) od dubine sample tačke, to znači da postoji geometrija između sample tačke i kamere -- ta tačka je "zaklonjena"
- Izračunaj procenat zaklonjenih tačaka -- to je occlusion faktor
// Pojednostavljen SSAO shader
float occlusion = 0.0;
float3 viewPos = ReconstructViewPosition(uv, depth);
float3 viewNormal = NormalBuffer.Sample(sampler, uv).xyz;
for (int i = 0; i < NUM_SAMPLES; i++)
{
// Nasumična tačka u hemisferi oko normale
float3 sampleOffset = RandomHemisphereDirection(i, viewNormal) * SampleRadius;
float3 samplePos = viewPos + sampleOffset;
// Projektuj sample na ekran
float2 sampleUV = ProjectToScreen(samplePos);
float sampleDepth = DepthBuffer.Sample(sampler, sampleUV);
// Da li je sample zaklonjen?
float sampleViewZ = LinearizeDepth(sampleDepth);
if (sampleViewZ < samplePos.z && abs(sampleViewZ - samplePos.z) < RangeCheck)
{
occlusion += 1.0;
}
}
occlusion = 1.0 - (occlusion / NUM_SAMPLES);
Problem: šum
Sa konačnim brojem sample-ova (tipično 16-64), rezultat je šuman (noisy). Rešenje: nakon SSAO pass-a, primenjuje se blur pass koji uravna šum. Ali blur mora biti "pametan" -- ne sme zamutiti AO preko granica dubine (inače bi AO "krvario" na susedne objekte). Koristi se bilateral blur ili depth-aware blur koji ignorise piksele sa drastično drugačijom dubinom.
Prednosti SSAO-a
- Radi na dinamičkim scenama bez prebaked podataka
- Relativno jeftin (0.3-0.5 ms na modernom GPU-u)
- Drastično poboljšava vizuelnu dubinu scene
Mane SSAO-a
- Low-frequency šum čak i nakon blur-a
- Težina sa fine-grain detaljima
- Haloing artefakti (tamni halos oko objekata)
HBAO (Horizon-Based Ambient Occlusion)
HBAO je poboljšana verzija SSAO-a, razvijena od strane NVIDIA-e (Louis Bavoil i Miguel Sainz, 2008). Umesto sampleovanja tačaka u sferi/hemisferi, HBAO koristi koncept horizonta.
Ključna razlika
Za svaki piksel, HBAO:
- Bira nekoliko smerova na 2D ekranu (tipično 4-8 radijanih pravaca)
- Za svaki smer, "marširera" duž tog smera na ekranu, čitajući dubine
- Na svakom koraku, izračunava ugao horizonta -- ugao od normale površine do linije koja spaja piksel i sampleovanu tačku
- Posmatra kako se horizont "podiže" kako se udaljava od piksela -- visoki horizont znači da je ta oblast zaklonjenja
Matematički, HBAO integriše vidljivost duž horizonta u svakom smeru, što je fizički preciznija aproksimacija ambient occlusion-a od prostog "broji zaklonjena sample-ova" pristupa SSAO-a.
Prednosti HBAO-a
- Manje haloing artefakata
- Fizički "tačniji" rezultat
- Bolje rukovanje glatkim površinama
Mane
- Skuplje od SSAO-a (0.5-1.0 ms)
- I dalje screen-space ograničenja
GTAO (Ground Truth Ambient Occlusion)
GTAO je moderna tehnika (Jimenez et al., 2016), korišćena kao podrazumevana AO tehnika u Unreal Engine 5. Ime sugestira: cilj je da se rezultat screen-space AO-a što više približi "ground truth"-u -- rezultatu koji bi dala potpuna offline GI simulacija.
Kako GTAO poboljšava stvari
GTAO se nadograđuje na HBAO pristup, ali sa važnim poboljšanjima:
-
Integrisanje vidljivosti po celom horizontu: Umesto diskretnog sampleovanja, GTAO analitički integriše vidljivost uzimajući u obzir tačan oblik horizonta.
-
Multi-bounce aproksimacija: Originalni SSAO i HBAO simuliraju samo jedno "odbijanje" -- koliko je tačka zaklonjenja od direktnog ambijentalnog svetla. GTAO dodaje aproksimaciju multi-bounce GI-a u zaklonjenim oblastima. Ovo sprečava da senke budu previše tamne, što je čest problem sa SSAO-om (u stvarnosti, čak i zatvoreni ugao dobija nešto indirektne svetlosti od odbijanja).
-
Spatial i temporal filtriranje: GTAO koristi agresivno filtriranje (i prostorno i vremensko) za smanjenje šuma bez gubitka detalja. Temporal filtriranje akumulira podatke iz prethodnih frejmova, što značajno poboljšava kvalitet bez povećanja cene jednog frejma.
-
Bolja integracija sa GI sistemima: GTAO u UE5 može da "sarađuje" sa Lumen-om, gde AO služi kao korekcija za oblasti gde Lumen nema dovoljno precizne informacije.
GTAO u UE5: podešavanja
- AO Intensity: Jačina efekta (0 = isključen, 1 = pun efekat)
- AO Radius: Radius sampleovanja u world space jedinicama. Veći radius = AO uhvati veće strukture ali gubi fine detalje.
- Quality: Kontroliše broj sample-ova (Low/Medium/High/Epic)
Ograničenja svih screen-space AO tehnika
Ovo je kritično da se razume: sve screen-space AO tehnike dele fundamentalna ograničenja:
-
Samo ono što je na ekranu: Ako objekat nije vidljiv na ekranu, ne doprinosi AO-u. Objekat koji je iza kamere, ili objekat koji je van frustuma, ne može da zakloni nijednu tačku na ekranu. Ovo može dovesti do vidljivih promena AO-a kada se objekat pojavi/nestane sa ivice ekrana.
-
Samo spoljašnjost: Screen-space AO vidi samo spoljašnje površine objekata (ono što je vidljivo kameri). Ne može da detektuje okluziju od geometrije koja je iza nečega drugog (jer depth buffer čuva samo najbližu površinu).
-
Zavisnost od rezolucije: Na nižim rezolucijama, AO gubi preciznost jer depth buffer ima manje piksela. Ovo je posebno vidljivo sa TSR/DLSS, gde se AO izračunava na internoj (nižoj) rezoluciji.
-
Nema okluzije od udaljenih objekata: Screen-space AO koristi ograničen radius. Velika struktura (zgrada, brdo) koja bi trebalo da zakloni nebo ne može biti uhvaćena jer je previše velika za AO radius.
Ova ograničenja su razlog zašto moderni engine-i koriste screen-space AO kao dopunu, ne zamenu za globalni AO. Lumen u UE5, na primer, pruža ambient occlusion kao deo svog GI izračunavanja, ali GTAO i dalje dodaje fine-scale detalje koje Lumen ne može da uhvati na svojoj rezoluciji.
15.9 Screen-Space Reflections (SSR)
Šta su Screen-Space Reflections?
Screen-Space Reflections (SSR) su post-processing tehnika za renderovanje refleksija koristeći samo podatke dostupne na ekranu -- scene color i depth buffer. Umesto da traži refleksije u 3D svetu (ray tracing, reflection probe-ovi), SSR "marširera" kroz depth buffer u screen space-u da pronađe tačku koja se reflektuje u posmatranom pikselu.
Kako SSR radi: Ray Marching kroz Depth Buffer
Za svaki piksel na ekranu koji ima dovoljno reflektivnu površinu (nizak roughness):
Korak 1: Odredi reflektovani vektor
float3 viewPos = ReconstructViewPosition(uv, depth);
float3 viewNormal = NormalBuffer.Sample(sampler, uv).xyz;
float3 viewDir = normalize(viewPos); // Smer od kamere do piksela
float3 reflectDir = reflect(viewDir, viewNormal); // Reflektovani smer
Korak 2: Ray march
Kreni od pozicije piksela u smeru reflektovanog vektora, korak po korak:
float3 rayPos = viewPos;
for (int i = 0; i < MaxSteps; i++)
{
rayPos += reflectDir * StepSize;
// Projektuj rayPos na ekran
float2 rayUV = ProjectToScreen(rayPos);
float sceneDepth = DepthBuffer.Sample(sampler, rayUV);
float rayDepth = rayPos.z;
// Da li je ray prošao "iza" neke geometrije?
if (rayDepth > sceneDepth)
{
// Pronašli smo interseckciju! Refleksija je boja piksela na rayUV
return SceneColor.Sample(sampler, rayUV);
}
}
// Nije pronađena interseckcija -- fallback na drugu refleksiju
return FallbackReflection(uv);
Vizuelno, zamislite da lansirate zrak iz piksela u smeru refleksije i da taj zrak "putuje" po ekranu. Na svakom koraku, proveravate: "Da li sam udario u neku površinu?" Ako jeste -- boja te površine je refleksija. Ako zrak izađe van ekrana ili nakon maksimalnog broja koraka ne pronađe ništa -- SSR nema rezultat i mora se koristiti fallback (reflection probe ili skybox).
Hi-Z Tracing (Hierarchical Z-Buffer Tracing)
Naivan ray march sa fiksnim korakom je spor: ili koristite mali korak (skup -- mnogo koraka) ili veliki korak (brz ali preskačete detalje i propuštate interseckcije).
UE5 koristi Hi-Z (Hierarchical Z-buffer) tracing za ubrzanje:
- Napravite mip chain za depth buffer: mip 0 = puna rezolucija, mip 1 = svaki 2×2 blok zamenje maksimalnom dubinom, mip 2 = svaki 4×4 blok, itd.
- Počnite marš na visokom mip nivou (veliki koraci, brzo preskačete prazne oblasti)
- Kada detektujete potencijalnu interseckciju, smanjite mip nivo (manji koraci, precizniji)
- Nastavite do mip 0 za tačnu interseckciju
Ovo drastično smanjuje broj koraka (i samim tim texture fetch-eva) potrebnih za pronalaženje interseckcije. Tipično, Hi-Z tracing zahteva 20-30 koraka umesto 100+ za naivan pristup.
Prednosti SSR-a
-
Besplatni detalj: SSR reflektuje sve što je na ekranu -- svaki objekat, svaki piksel. Reflection probe-ovi imaju ograničenu rezoluciju i ne hvataju dinamičke objekte (osim ako se ne ažuriraju u realnom vremenu, što je skupo). SSR daje piksel-savršene refleksije bez dodatnog troška.
-
Dinamičan: SSR automatski reflektuje pokretne objekte, promene osvetljenja, particle efekte -- sve što je vidljivo na ekranu.
-
Lokalne refleksije: Za refleksije na podu, na vodi, na sjajnim površinama -- SSR je često vizuelno superioran u odnosu na probe-ove jer hvata lokalne detalje.
Ograničenja SSR-a
-
Ne može reflektovati ono što nije na ekranu: Ovo je fundamentalno ograničenje. Ako objekat nije vidljiv kameri, SSR ga ne može reflektovati. Ovo je posebno problematično za:
- Objekte iza kamere
- Objekte van ivice ekrana
- Samorefleksije (objekat ne može videti svoju donju stranu u refleksiji jer depth buffer čuva samo spoljašnju površinu)
-
Artefakti na ivicama ekrana: Kako se reflektovani zrak približava ivici ekrana, sve je verovatnije da će pogoditi oblast za koju nemamo podatke. Ovo uzrokuje "nestajanje" refleksija na ivicama, što je vizuelno primetan artefakt. UE5 ovo ublažava fade-out-om refleksija blizu ivica.
-
Performansa varira sa roughness-om: Za glatke površine (nizak roughness), jedan zrak po pikselu je dovoljan. Za hrapave površine, potrebno je više zraka (da bi se aproksimirala distribucija refleksija), što dramatično povećava cenu.
-
Problemi sa tankim objektima: Veoma tanki objekti (travke, grane, žice) su teški za SSR jer ih ray march može "preskočiti" (korak je veći od debljine objekta).
SSR i roughness
Površine sa visokim roughness-om (npr. hrapav beton) imaju "razmrljane" refleksije u stvarnosti. Za SSR, ovo se implementira tako što se za svaki piksel lansira više zraka u slučajnim smerovima raspoređenim oko reflektovanog smera, u skladu sa roughness distribucijom (GGX distribution iz PBR-a, poglavlje 11). Rezultat se prosečuje.
UE5 optimizuje ovo na nekoliko načina:
- Koristi temporal accumulation (akumulira rezultate iz prethodnih frejmova)
- Na višim roughness vrednostima, može čitati iz blur-ovanog scene color-a umesto da lansira više zraka
- Iznad određenog roughness praga (tipično 0.4-0.5), SSR se potpuno isključuje i engine se oslanja na reflection probe-ove
Kako UE5 kombinuje SSR sa drugim metodama refleksije
UE5 koristi hijerarhijski pristup refleksijama:
1. Lumen refleksije (ako je Lumen uključen) -- ray traced / screen traced refleksije
2. SSR (Screen-Space Reflections) -- jeftine, lokalne refleksije
3. Reflection Captures (Probe-ovi) -- precomputed, pokrivaju šire oblasti
4. Skybox / Default reflection -- fallback za površine koje ništa drugo ne pokriva
Svaki nivo ima svoju "zonu odgovornosti":
- SSR pokriva ono što je vidljivo na ekranu
- Reflection probe-ovi popunjavaju oblast van ekrana
- Skybox pokriva nebo i veoma udaljene refleksije
Blending između ovih nivoa je automatski i baziran na pouzdanosti svakog izvora. SSR piksel koji je pronašao validnu interseckciju ima visoku pouzdanost i dominira. SSR piksel koji je blizu ivice ekrana (ili nije pronašao interseckciju) ima nisku pouzdanost i fade-uje prema probe/skybox refleksijama.
Performanse SSR-a
SSR cena tipično iznosi:
| Kvalitet | Approx. cena (1080p) | Approx. cena (4K) |
|---|---|---|
| Low | 0.3-0.5 ms | 0.8-1.5 ms |
| Medium | 0.5-1.0 ms | 1.5-3.0 ms |
| High | 1.0-2.0 ms | 3.0-5.0 ms |
| Epic | 1.5-3.0 ms | 4.0-8.0 ms |
Cena je proporcionalna broju koraka ray march-a, broju zraka po pikselu (za rough površine), i rezoluciji. Na scenama sa mnogo reflektivnih površina i niskim roughness-om, SSR može biti značajan potrošač GPU vremena.
15.10 Anti-Aliasing -- detaljna analiza
Šta je aliasing?
Aliasing je vizuelni artefakt koji nastaje kada se kontinualni signal (3D scena) diskretizuje u konačan broj piksela. Najočiglednija manifestacija: "stepenice" (jagged edges) na ivicama objekata. Dijagonalna linija, umesto da bude glatka, izgleda kao niz stepenica jer svaki piksel može biti samo "potpuno unutra" ili "potpuno van" objekta.
Ali aliasing se ne pojavljuje samo na ivicama geometrije. Javlja se svuda gde postoji visokofrekventni detalj koji ne može biti adekvatno predstavljen na rezoluciji ekrana:
- Geometrijski aliasing: Stepenice na ivicama trouglova
- Shader aliasing: Treperenje spekularne refleksije (specular aliasing)
- Teksturni aliasing: Moiré pattern-i na udaljenim teksturama (mip-mape ovo ublažavaju, poglavlje 05)
- Sub-pixel aliasing: Objekti manji od piksela (žice, antene, trava) nestaju i pojavljuju se dok se kamera kreće
MSAA (Multi-Sample Anti-Aliasing)
Princip
MSAA je hardverska anti-aliasing tehnika koja radi na nivou rasterizera. Umesto da testira pokrivanje (coverage) svakog piksela jednom tačkom u centru, MSAA testira pokrivanje sa više tačaka (sample-ova) unutar piksela.
Tipično: 2×, 4×, ili 8× MSAA znači 2, 4, ili 8 sample tačaka po pikselu. Za svaki piksel, rasterizer proverava koliko od tih tačaka pada unutar trougla. Pixel shader se i dalje izvršava samo jednom po pikselu (ne jednom po sample-u!), ali se rezultat "razmazuje" u skladu sa pokrivanjem:
4× MSAA, piksel na ivici trougla:
┌───────────────┐
│ · · │ · = sample tačka
│ ▲ │ ▲ = ivica trougla prolazi ovde
│ · ● │ ● = sample tačka unutar trougla
│ │
└───────────────┘
Rezultat: 1 od 4 sample-ova je unutar trougla → piksel dobija 25% boje trougla
Ovo efektivno stvara glatke prelaze na ivicama geometrije -- piksel koji je delimično pokriven trouglom dobija polu-transparentnu boju, umesto pune boje ili nikakve.
MSAA i Deferred Rendering
Ovde je ključni problem: MSAA je veoma skup sa deferred rendering-om. U deferred pipeline-u (koji UE5 koristi kao podrazumevani), osvetljenje se izračunava u posebnom lighting pass-u koji čita iz G-Buffer-a. Ako koristite 4× MSAA, G-Buffer mora da čuva 4× više podataka (4 sample-a po pikselu za svaki buffer -- normal, albedo, roughness, depth...). Ovo drastično povećava memorijsku potrošnju i bandwidth zahteve.
Iz tog razloga, MSAA se retko koristi sa deferred rendering-om. UE5 ga podržava samo u forward rendering modu, koji se koristi za mobilne platforme i specifične slučajeve (VR, npr.).
MSAA memorijska cena (G-Buffer):
1× (bez MSAA): ~40 MB za G-Buffer na 1080p
4× MSAA: ~160 MB za G-Buffer na 1080p (4× više!)
8× MSAA: ~320 MB za G-Buffer na 1080p (8× više!)
Prednosti MSAA
- Hardverski ubrzano -- efikasno na GPU-u (kada se koristi sa forward rendering-om)
- Čiste, oštre ivice bez zamućenja
- Ne utiče na oštrinu tekstura i shadera (samo ivice geometrije)
Mane MSAA
- Praktično neupotrebljiv sa deferred rendering-om (preskup)
- Ne rešava shader aliasing (specular treperenje, itd.)
- Ne rešava sub-pixel aliasing
- Memorijski intenzivan na višim nivoima (4×, 8×)
FXAA (Fast Approximate Anti-Aliasing)
Princip
FXAA (Timothy Lottes, NVIDIA, 2009) je potpuno drugačiji pristup: umesto da radi na hardverskom nivou tokom rasterizacije, FXAA je post-processing pass koji se primenjuje na već renderovanu sliku.
FXAA analizira finalnu sliku i traži ivice -- oblasti sa visokim kontrastom između susednih piksela. Kada pronađe ivicu, blago zamutira piksele duž te ivice da bi stvorio iluziju glatkog prelaza.
Algoritam (pojednostavljeno)
-
Edge detection: Za svaki piksel, izračunaj luminansu i poredi sa susedima (gore, dole, levo, desno, dijagonalno). Ako je kontrast iznad praga → ivica.
-
Edge direction: Odredi smer ivice (horizontalna ili vertikalna) na osnovu rasporeda kontrastnih piksela.
-
Edge endpoint search: Pronađi krajeve ivice -- tačke gde kontrast prestaje.
-
Sub-pixel blending: Na osnovu smera i dužine ivice, pomeri UV koordinatu za sampleovanje boje. Ovo efektivno "pomera" piksel blago duž ivice, stvarajući glatkiji prelaz.
// Koncept FXAA (veoma pojednostavljeno)
float lumaN = Luminance(texture.Sample(sampler, uv + float2(0, -1/height)));
float lumaS = Luminance(texture.Sample(sampler, uv + float2(0, 1/height)));
float lumaE = Luminance(texture.Sample(sampler, uv + float2( 1/width, 0)));
float lumaW = Luminance(texture.Sample(sampler, uv + float2(-1/width, 0)));
float lumaCenter = Luminance(texture.Sample(sampler, uv));
float rangeMax = max(max(lumaN, lumaS), max(lumaE, lumaW));
float rangeMin = min(min(lumaN, lumaS), min(lumaE, lumaW));
float range = rangeMax - rangeMin;
if (range < EdgeThreshold)
return texture.Sample(sampler, uv); // Nema ivice, vrati original
// ... edge direction, endpoint search, sub-pixel blending ...
Prednosti FXAA
- Izuzetno jeftin: Jedan full-screen pass, ~0.1-0.2 ms
- Radi sa bilo kojim rendering pipeline-om: Deferred, forward, hybrid -- svejedno
- Pokriva SVE tipove aliasinga: Geometrijski, shader, teksturni -- jer radi na finalnoj slici
- Jednostavna integracija: Jedan shader, bez posebne infrastrukture
Mane FXAA
- Zamućuje sliku: FXAA ne pravi razliku između ivice geometrije i detaljne teksture. Može zamutiti tekst, fine linije, i oštre detalje tekstura.
- Ne rešava temporal aliasing: Treperenje (flickering) od frejma do frejma nije adresirano jer FXAA gleda samo trenutni frejm.
- Kvalitet je ograničen: Na teškim slučajevima (veoma tanke linije, sub-pixel detalji), FXAA ne može pomoći.
TAA (Temporal Anti-Aliasing)
Princip
TAA (Temporal Anti-Aliasing) je moderna tehnika koja koristi podatke iz prethodnih frejmova da poboljša kvalitet anti-aliasinga. TAA je danas dominantan pristup u AAA igrama i koristi se kao podrazumevani AA u UE5.
Ključna ideja: umesto da pokušavate da rešite aliasing u jednom frejmu (što zahteva mnogo sample-ova), rasporedite sample-ove preko više frejmova i akumulirajte rezultate.
Kako radi
Korak 1: Jittered camera
Svaki frejm, kamera se blago pomeri -- ne u svetu, već na sub-pixel nivou. Projekciona matrica se modifikuje da pomeri poziciju piksela za mali offset (tipično manje od jednog piksela). Svaki frejm koristi drugačiji offset iz predefinisanog pattern-a (Halton sekvence su popularan izbor).
Frejm 1: offset (0.25, 0.25)
Frejm 2: offset (0.75, 0.25)
Frejm 3: offset (0.25, 0.75)
Frejm 4: offset (0.75, 0.75)
... i tako dalje
Ovo znači da svaki frejm "vidi" scenu sa blago drugačije pozicije unutar piksela. Tokom 4-8 frejmova, efektivno sampleujete scenu sa 4-8× gustoćom -- slično kao 4-8× super-sampling, ali raspoređen preko vremena.
Korak 2: History buffer i reprojection
TAA čuva rezultat prethodnog frejma u history buffer-u. Za svaki piksel u trenutnom frejmu, engine koristi motion vector-e (velocity buffer) da pronađe gde je taj piksel bio u prethodnom frejmu i čita odgovarajuću boju iz history buffer-a.
Ovaj proces se zove reprojection -- "gde je ovaj piksel bio u prošlom frejmu?" Ako je scena statična, piksel je na istom mestu. Ako se kamera pomakla ili se objekat pomerio, motion vector govori tačno gde treba tražiti.
Korak 3: Blending (mešanje)
Trenutni frejm se meša sa reprojektovanim history buffer-om:
float3 currentColor = CurrentFrame.Sample(sampler, uv);
float3 historyColor = HistoryBuffer.Sample(sampler, reprojectedUV);
// Clamp history na opseg boja suseda u trenutnom frejmu (neighborhood clamping)
float3 nearMin, nearMax;
ComputeNeighborhoodMinMax(uv, nearMin, nearMax);
historyColor = clamp(historyColor, nearMin, nearMax);
float3 result = lerp(historyColor, currentColor, BlendFactor); // tipično 0.04-0.1
Primetite BlendFactor od 0.04-0.1 -- to znači da je 90-96% finalne boje iz history buffer-a, i samo 4-10% iz trenutnog frejma. Ovo daje izuzetnu stabilnost i glatkost, ali zahteva pažljivo rukovanje da se izbegnu artefakti.
Korak 4: Neighborhood clamping
Ovo je ključni korak koji sprečava "ghosting" artefakte. Bez njega, history buffer bi mogao sadržavati zastarele podatke (objekat koji se pomerio, ali history buffer još uvek sadrži njegovu staru poziciju). Neighborhood clamping ograničava boju iz history buffer-a na opseg boja koji postoji u okolini piksela u trenutnom frejmu. Ako history boja ispadne van tog opsega, znamo da je zastarela i "prisiljavamo" je da se uklopi.
Ghosting problem
Ghosting je najpoznatiji artefakt TAA-a. Nastaje kada reprojection ne uspe da tačno prati objekat (neprecizni motion vektori, disocclusion -- kada objekat koji je bio zaklonjen postane vidljiv). Rezultat: senka ili "duh" prethodne pozicije objekta je vidljiv na kratko.
Engine-i ovo rešavaju agresivnijim neighborhood clamping-om i detekcijom neslaganja. Kada se detektuje neslaganje, blend factor se privremeno povećava (više uticaja trenutnog frejma, manje history-ja), čime se ghosting brže "čisti" na račun privremeno nešto nižeg kvaliteta AA.
Prednosti TAA
- Odličan kvalitet: Efektivni super-sampling bez pune cene
- Pokriva SVE tipove aliasinga: Geometrijski, shader, sub-pixel, temporal
- Stabilnost: Slika ne treperi između frejmova
- Osnova za upscaling: TAA je temelj za TSR i DLSS (videti ispod)
Mane TAA
- Ghosting: Zastareli podaci iz history buffer-a mogu izazvati "duhove"
- Zamućenje u pokretu: Agresivno blending-ovanje sa history buffer-om može dovesti do percipiranog gubitka oštrine tokom brzog pokreta
- Zahteva motion vektore: Svi pokretni objekti moraju generisati korektne motion vektore, inače TAA ne može da ih ispravno prati
- Cena: ~0.3-0.5 ms (jeftinije od MSAA ali skuplje od FXAA)
TSR (Temporal Super Resolution)
Šta je TSR?
TSR (Temporal Super Resolution) je Unreal Engine 5 ugrađeni upscaling sistem. TSR uzima TAA koncept korak dalje: umesto da renderuje na punoj rezoluciji i primeni AA, TSR renderuje na nižoj internoj rezoluciji i koristi temporalnu akumulaciju da rekonstruiše sliku na punoj display rezoluciji.
Tradicionalni TAA: Render na 1080p → TAA → Output 1080p
TSR: Render na 720p → TSR → Output 1080p
Kako radi
TSR koristi iste principe kao TAA (jitter, history buffer, reprojection, neighborhood clamping), ali sa dodacima:
-
Subpixel detalj iz temporalne akumulacije: Pošto se kamera jitter-uje na sub-pixel nivou, a interni render je na nižoj rezoluciji, svaki frejm vidi blago drugačije sub-piksele scene. TSR akumulira ove informacije i rekonstruiše detalje koji ne postoje ni u jednom pojedinačnom frejmu.
-
Pametniji rejection/clamping: TSR koristi sofisticiraniji algoritam za odlučivanje koliko da veruje history buffer-u. Umesto prostog neighborhood clamping-a, koristi informacije o pouzdanosti (confidence) bazirane na koliko se dobro podudaraju trenutni i history podaci.
-
Sharpening pass: Nakon rekonstrukcije, TSR primenjuje sharpening (izoštravanje) da bi kompenzovao inherentnu mekoću upscaled slike.
Kvalitet TSR-a
Kvalitet TSR-a zavisi od odnosa interne i izlazne rezolucije:
| Screen Percentage | Interna rez (za 1080p output) | Kvalitet |
|---|---|---|
| 100% | 1920×1080 | Identično TAA-u |
| 75% | 1440×810 | Odličan -- teško razlikovati od nativnog |
| 66% | 1267×713 | Veoma dobar -- blagi gubitak detalja |
| 50% | 960×540 | Dobar -- primetan gubitak na finim detaljima |
Screen Percentage od 75% je "sweet spot" za većinu projekata -- dobijate ~44% manje piksela za renderovanje (značajno ubrzanje) sa minimalnim gubitkom kvaliteta.
Prednosti TSR
- Ugrađen u UE5 -- nema zavisnosti od specifičnog hardvera
- Radi na svim platformama (PC, konzole, mobilni)
- Značajno ubrzanje performansi (renderovanje na nižoj rezoluciji)
- Kvalitet vrlo blizak nativnoj rezoluciji na 75% screen percentage
Mane TSR
- Može imati ghosting (isti problem kao TAA, ali može biti izraženiji zbog niže interne rezolucije)
- Na veoma niskim screen percentage vrednostima (ispod 50%), kvalitet značajno opada
- Zahteva korektne motion vektore za sve pokretne objekte
DLSS i FSR: ekosistem upscalinga
Pored TSR-a, postoje i rešenja specifična za hardware vendore:
NVIDIA DLSS (Deep Learning Super Sampling)
DLSS koristi neuralnu mrežu (treniranu na NVIDIA-inim superračunarima) za upscaling slike. Umesto ručno pisanog algoritma (kao TSR), DLSS koristi AI model koji je naučio kako da rekonstruiše visoko-rezolucionu sliku iz nisko-rezolucione na osnovu miliona primera.
Ključne razlike od TSR:
- Zahteva NVIDIA RTX GPU (koristi specijalizovane Tensor jezgra)
- Potencijalno veći kvalitet na nižim internim rezolucijama (AI model bolje "izmišlja" detalje)
- "Crna kutija" -- ne znate tačno šta AI radi, manja kontrola
AMD FSR (FidelityFX Super Resolution)
FSR postoji u dve varijante:
- FSR 1.0: Prostorni upscaler (ne koristi temporalne podatke). Primenjuje edge-aware upscaling i sharpening. Jednostavan ali manje kvalitetan.
- FSR 2.0+: Temporalni upscaler sličan TSR-u. Koristi motion vektore i history buffer za rekonstrukciju. Ne zahteva specijalizovani hardver -- radi na bilo kojem GPU-u.
Poređenje
| Tehnika | Zahteva specifičan HW | Temporalna | Kvalitet na 50% | Cena |
|---|---|---|---|---|
| TSR | Ne | Da | Dobar | ~0.5-1.0 ms |
| DLSS 3.x | NVIDIA RTX | Da | Odličan | ~0.3-0.5 ms (Tensor cores) |
| FSR 2.x | Ne | Da | Dobar | ~0.5-1.0 ms |
| FXAA | Ne | Ne | N/A (nije upscaler) | ~0.1-0.2 ms |
Koji AA izabrati?
Evo praktičnog vodiča:
| Scenario | Preporuka |
|---|---|
| UE5 igra, deferred rendering, ciljate konzole | TSR na 75% screen percentage |
| UE5 igra, ciljate PC sa NVIDIA RTX | DLSS ako je dostupan, inače TSR |
| UE5 igra, forward rendering, mobilni | MSAA 2×-4× ili FXAA |
| Niski budžet performansi, stari hardver | FXAA |
| Filmski rad, offline rendering | TAA na punoj rezoluciji (ili čak super-sampling) |
| VR igra | MSAA 4× (forward rendering) + FXAA |
15.11 Redosled post-processing prolaza u UE5
Redosled u kojem UE5 primenjuje post-processing efekte je pažljivo optimizovan. Evo približnog redosleda (pojednostavljeno, aktuelna implementacija može varirati između verzija engine-a):
1. Motion Blur Setup (velocity buffer je generisan tokom base pass-a)
2. Screen-Space Ambient Occlusion (GTAO)
3. Screen-Space Reflections (SSR)
4. Temporal Anti-Aliasing / TSR (rana faza)
↓
--- HDR prostor (scene color je još uvek u HDR) ---
↓
5. Bloom
a. Bright pass (threshold)
b. Downsample chain
c. Blur na svakom nivou
d. Upsample i composite
6. Auto-Exposure (histogram, EV izračunavanje)
7. Exposure primena (množenje scene color-a sa exposure vrednošću)
8. Tone Mapping (ACES / GT / custom)
↓
--- LDR prostor (scene color je sada u 0-1 opsegu) ---
↓
9. Color Grading (LUT, saturacija, kontrast, itd.)
10. Depth of Field (može biti i ranije, zavisi od konfiguracije)
11. Motion Blur (konačna primena)
12. Chromatic Aberration
13. Film Grain / Vignette / Lens Flare
14. TAA / TSR (finalna faza -- temporal resolve)
15. FXAA (ako je uključen kao dodatni pass)
16. Gamma Correction / Output Transform
17. UI Overlay
Zašto ovaj redosled?
Nekoliko ključnih razmišljanja:
-
Bloom pre tone mappinga: Bloom radi na HDR vrednostima gde svetli pikseli zaista imaju visoke vrednosti. Nakon tone mappinga, sve je u 0-1 opsegu i bloom bi bio manje efektan.
-
Exposure pre tone mappinga: Tone mapping krivulja očekuje ulaz u određenom opsegu. Exposure prilagođava taj opseg.
-
DOF i Motion Blur nakon tone mappinga: Ovi efekti sampleuju scene color i mešaju boje piksela. Ako rade na HDR vrednostima, svetli pikseli bi mogli dominirati blur-om na nerealan način. Rad na LDR-u daje vizuelno konzistentnije rezultate (mada ovo je tema debate -- neki engine-i rade DOF u HDR prostoru).
-
Chromatic aberration kasno: CA uvodi distorziju koju raniji prolazi ne bi trebalo da "vide". Ako bi CA bio pre DOF-a, DOF bi zamutio CA artefakte.
-
TAA/TSR na kraju: TAA/TSR treba da vidi finalnu sliku da bi pravilno akumulirao podatke za temporal stabilnost.
-
FXAA poslednji (ako se koristi): FXAA čisti preostale ivice koje TAA/TSR nisu uhvatili.
Post Process Volume u UE5
U UE5, sva post-processing podešavanja se kontrolišu kroz Post Process Volume -- nevidljivi aktor koji definiše oblast u kojoj važe određena podešavanja. Možete imati:
- Globalni PPC Volume: Infinite extent, pokriva celu scenu. Definiše podrazumevana podešavanja.
- Lokalni PPC Volume: Ograničen na specifičnu oblast (sobu, hodnik, otvoreni prostor). Kada kamera uđe u taj volumen, podešavanja se blenduju sa globalnim.
Blending između Volume-a je automatski i baziran na prioritetu (Priority property). Volume sa višim prioritetom prepisuje onaj sa nižim. Blend Weight kontroliše koliko Volume utiče na finalnu sliku (0 = nema uticaja, 1 = potpuni uticaj).
Ovo je izuzetno moćan sistem za kontrolu vizuelnog stila igre po oblastima:
- Mračna pećina: niži exposure, jači AO, hladniji color grading
- Sunčan eksterijer: viši exposure, topliji ton, bloom
- Underwater zona: plavi tint, jači DOF, chromatic aberration
- Horror sekvenca: desaturisano, jak vignette, grain
15.12 Rezime ključnih pojmova
| Pojam | Objašnjenje |
|---|---|
| Post-Processing | Vizuelni efekti primenjeni na 2D sliku nakon završetka 3D renderovanja |
| Full-Screen Pass | Shader koji se izvršava za svaki piksel na ekranu, čitajući iz jednog RT i pišući u drugi |
| Ping-Pong Rendering | Tehnika naizmeničnog korišćenja dva render target-a za sekvencijalne efekte |
| Bloom | Efekat "krvareenja" svetlosti oko jarkih oblasti, simulira difuziju u oku/objektivu |
| Bright Pass / Threshold | Izdvajanje piksela iznad određene luminanse za bloom obradu |
| Tone Mapping | Konverzija HDR vrednosti u LDR opseg za prikaz na ekranu |
| ACES | Academy Color Encoding System -- industrijski standard za filmsku obradu boja i tone mapping |
| Filmic Curve | S-krivulja tone mappinga koja simulira karakteristiku filmske trake |
| GT Tone Mapper | Alternativni tone mapper u UE5 sa boljim očuvanjem zasićenosti boja |
| HDR | High Dynamic Range -- opseg vrednosti koji prevazilazi mogućnosti prikaza |
| LDR | Low Dynamic Range -- opseg vrednosti 0-1 koji displej može prikazati |
| Exposure | Množilac koji kontroliše ukupnu osvetljenost scene pre tone mappinga |
| Auto-Exposure | Automatsko prilagođavanje ekspozicije na osnovu distribucije osvetljenosti u sceni |
| EV100 | Exposure Value pri ISO 100 -- standardna mera ekspozicije iz fotografije |
| Histogram | Distribucija luminansi piksela, koristi se za auto-exposure |
| Adaptation Speed | Brzina prilagođavanja auto-exposure-a (odvojeno za svetlo→tamno i tamno→svetlo) |
| Motion Blur | Zamućenje pokreta, simulira otvoreni zatvarač kamere |
| Velocity Buffer | Render target koji čuva 2D vektor pomeranja svakog piksela između frejmova |
| Per-Object Motion Blur | Motion blur specifičan za pokretne objekte (zahteva velocity buffer) |
| Camera Motion Blur | Motion blur uzrokovan pokretom kamere (cela slika se pomera) |
| Depth of Field (DOF) | Zamućenje objekata van fokusne ravni, simulira ponašanje sočiva |
| Circle of Confusion (CoC) | Veličina zamućenog diska za piksel van fokusa -- funkcija rastojanja od fokusne ravni i aperture |
| Near/Far DOF | Zamućenje objekata ispred/iza fokusne ravni |
| Gaussian DOF | Jeftina implementacija DOF-a sa Gaussian blur-om |
| Bokeh DOF | Vizuelno ubedljiva ali skupa implementacija sa diskretnim bokeh oblicima |
| Cinematic DOF | Moderna implementacija u UE5 koja balansira kvalitet i performanse |
| Chromatic Aberration | Razdvajanje boja na periferiji slike, simulira disperziju u sočivu |
| Ambient Occlusion (AO) | Mera koliko je tačka na površini zaklonjena od ambijentalnog svetla |
| SSAO | Screen-Space Ambient Occlusion -- Crytek-ova originalna tehnika (2007) |
| HBAO | Horizon-Based AO -- NVIDIA-ina poboljšana verzija sa horizont-baziranim sampleovanjem |
| GTAO | Ground Truth AO -- moderna tehnika korišćena u UE5, najbliža "tačnom" rezultatu |
| Bilateral Blur | Blur koji poštuje granice dubine -- ne zamućuje AO preko ivica objekata |
| Screen-Space Reflections (SSR) | Refleksije izračunate ray march-om kroz depth buffer |
| Ray Marching | Tehnika praćenja zraka korak po korak kroz prostor (u ovom kontekstu, screen space) |
| Hi-Z Tracing | Ubrzani ray march koristeći hijerarhijski Z-buffer (mip chain depth buffer-a) |
| Aliasing | Vizuelni artefakt nastao diskretizacijom kontinualnog signala (stepenice, treperenje) |
| MSAA | Multi-Sample AA -- hardverska tehnika sa više sample tačaka po pikselu |
| FXAA | Fast Approximate AA -- post-process edge detection i zamućenje |
| TAA | Temporal AA -- akumulacija podataka iz prethodnih frejmova za redukciju aliasinga |
| Jittered Camera | Sub-pikselno pomeranje kamere svaki frejm za temporalno sampleovanje |
| History Buffer | Render target koji čuva rezultat prethodnog frejma za TAA/TSR |
| Reprojection | Mapiranje piksela iz prethodnog frejma na poziciju u trenutnom frejmu pomoću motion vektora |
| Neighborhood Clamping | Ograničavanje boje iz history buffer-a na opseg boja susednih piksela u trenutnom frejmu |
| Ghosting | Artefakt TAA/TSR-a gde "duh" prethodne pozicije objekta privremeno ostaje vidljiv |
| TSR | Temporal Super Resolution -- UE5 upscaling sistem koji renderuje na nižoj rezoluciji |
| Screen Percentage | Odnos interne render rezolucije i izlazne rezolucije (npr. 75% = render na 75% display rez.) |
| DLSS | Deep Learning Super Sampling -- NVIDIA AI-bazirani upscaler (zahteva RTX hardver) |
| FSR | FidelityFX Super Resolution -- AMD-ov upscaler (radi na svim GPU-ovima) |
| Post Process Volume | UE5 aktor koji definiše post-processing podešavanja za određenu oblast scene |
15.13 Dodatna literatura i linkovi
Bloom
- Kawase, M. "Frame Buffer Postprocessing Effects in DOUBLE-S.T.E.A.L" (GDC 2003) -- originalni Kawase blur
- Jimenez, J. "Next Generation Post Processing in Call of Duty: Advanced Warfare" (SIGGRAPH 2014) -- dual Kawase blur i moderni bloom pristup
Tone Mapping
- Reinhard, E. et al. "Photographic Tone Reproduction for Digital Images" (SIGGRAPH 2002) -- originalni Reinhard operator
- Hable, J. "Filmic Tonemapping Operators" (2010) -- Uncharted 2 tone mapper
- Narkowicz, K. "ACES Filmic Tone Mapping Curve" (2015) -- popularan blog post o ACES implementaciji
- Uchimura, H. "HDR Theory and Practice" (CEDEC 2017) -- GT tone mapper
- Selan, J. "Cinematic Color" (SIGGRAPH 2012) -- ACES i color management u filmskoj produkciji
Auto-Exposure
- UE5 dokumentacija: "Auto Exposure (Eye Adaptation)" -- praktični vodič za UE5 podešavanja
Motion Blur
- Green, S. "A Reconstruction Filter for Plausible Motion Blur" (I3D 2003)
- McGuire, M. et al. "A Fast and Stable Feature-Aware Motion Blur Filter" (HPG 2012)
Depth of Field
- Potmesil, M. & Chakravarty, I. "A Lens and Aperture Camera Model for Synthetic Image Generation" (SIGGRAPH 1981) -- teorijski temelj
- Lee, S. et al. "Practical Real-Time Lens-Flare Rendering" (Eurographics 2013)
- UE5 dokumentacija: "Cinematic Depth of Field" -- detalji Diaphragm DOF implementacije
Ambient Occlusion
- Mittring, M. "Finding Next Gen - CryEngine 2" (SIGGRAPH 2007) -- originalni SSAO iz Crysis-a
- Bavoil, L. & Sainz, M. "Screen Space Ambient Occlusion" (NVIDIA 2008) -- HBAO
- Jimenez, J. et al. "Practical Realtime Strategies for Accurate Indirect Occlusion" (SIGGRAPH 2016) -- GTAO
Screen-Space Reflections
- McGuire, M. & Mara, M. "Efficient GPU Screen-Space Ray Tracing" (JCGT 2014) -- Hi-Z tracing
Anti-Aliasing
- Lottes, T. "FXAA" (NVIDIA 2009) -- originalni FXAA whitepaper
- Karis, B. "High Quality Temporal Supersampling" (SIGGRAPH 2014) -- TAA implementacija u UE4, osnova za UE5
- UE5 dokumentacija: "Temporal Super Resolution" -- TSR vodič
Povezana poglavlja u ovoj knjizi
- Poglavlje 05: Teksture i render target-i -- fundamentalno za razumevanje ping-pong renderinga i G-Buffer-a
- Poglavlje 07: Render Pipeline -- kontekst u koji se post-processing uklapa
- Poglavlje 11: PBR -- roughness, metalness, i veza sa refleksijama i AO
- Poglavlje 12: Globalna iluminacija -- kako se AO uklapa u širu sliku osvetljenja
- Poglavlje 16: Nauka o boji (Color Science) -- dublja analiza color space-ova, gamuta, i color grading-a koji su usko povezani sa tone mapping-om
U sledećem poglavlju (Poglavlje 16) zaronićemo u nauku o boji -- kako boje funkcionišu, šta su color space-ovi, kako razumeti gamut, i kako color grading transformiše "look" vaše igre. Tone mapping koji smo ovde opisali je samo ulazna tačka u mnogo širi svet upravljanja bojama.