Poglavlje 26: Lumen Refleksije

Poglavlje 26: Lumen Refleksije


"Svet bez refleksija je svet bez dubine. Tek kada površina vrati sliku okoline, naš mozak je prihvata kao stvarnu."


Uvod

Dobrodošli u jedno od najzanimljivijih poglavlja ove knjige. Ako ste prošli kroz Poglavlje 25, gde smo detaljno obradili kako Lumen rešava Global Illumination (GI) -- indirektno osvetljenje koje scenu čini živom -- sada je vreme da se pozabavimo drugom stranom medalje: refleksijama.

Refleksije su, na prvi pogled, jednostavan koncept. Svetlost udari u površinu i odbije se. Ogledalo pokazuje vašu sliku, lokva na ulici reflektuje nebo, čelik automobila preslikava okolne zgrade. Ali u svetu real-time renderinga, refleksije su decenijama bile jedan od najtežih problema. Razlog je jednostavan: da biste korektno prikazali refleksiju, morate znati kako scena izgleda iz ugla reflektovane površine, a ne iz ugla kamere. To, u suštini, znači da morate renderovati scenu ponovo -- iz drugog ugla. Za svaku reflektivnu površinu. Za svaki frame.

Lumen menja pravila igre. Umesto da se oslanjamo na statične cubemap snimke ili skupe planar reflection renderinge, Lumen koristi višeslojni sistem koji kombinuje različite tehnike po principu kvaliteta i cene: počinje od najjeftinijeg pristupa i eskalira ka skupljim metodama samo kada je to neophodno.

U ovom poglavlju ćemo proći kroz:

Pripremite se -- ovo poglavlje je tehničko, ali ćemo ga prolaziti korak po korak.


26.1 Problem refleksija

26.1.1 Šta refleksija zapravo jeste

Krenimo od fizike. Kada foton svetlosti udari u savršeno glatku površinu, odbija se pod uglom jednakim uglu upada -- to je zakon refleksije koji ste učili u školi. Za ogledalo, ovo znači da svaki piksel koji gledate na površini ogledala zapravo prikazuje ono što biste videli da pogledate u pravcu reflektovanog zraka.

U PBR (Physically Based Rendering) sistemu koji smo obradili u Poglavlju 11, refleksije su deo specular komponente materijala. Roughness parametar kontroliše koliko su refleksije oštre ili zamagljene:

Ključna stvar je sledeća: svaki materijal ima refleksije. Čak i beton. Samo što su kod grubih materijala refleksije toliko zamućene da ih percipiramo kao opšte osvetljenje, a ne kao odraz okoline. Lumen to koristi -- za veoma grube površine, GI sistem (Poglavlje 25) već pokriva ovu komponentu. Ali za glatke i polu-glatke površine, potreban nam je dedicirani reflection sistem.

26.1.2 Zašto su refleksije teške u real-time renderingu

Da biste razumeli zašto su refleksije problem, zamislite sledeći scenario: stojite u sobi sa ogledalom na zidu. Kamera gleda u ogledalo. Da biste korektno prikazali sliku u ogledalu, morate znati kako soba izgleda iz ugla ogledala. To znači:

  1. Potreban vam je drugi render pass -- morali biste da renderujete celu scenu iz perspektive ogledala.
  2. Za svaku reflektivnu površinu -- ako imate tri ogledala, to su tri dodatna renderovanja.
  3. Refleksije u refleksijama -- ogledalo koje reflektuje drugo ogledalo zahteva rekurzivne renderinge. Ovo eksponencijalno raste.
  4. Svaki frame -- scena je dinamična, pa sve ovo morate raditi svakog frejma.

Čak i za jedno ogledalo, duplirati ceo render pipeline je izuzetno skupo. Zamislite igru sa vodom, staklenim površinama, metalnim podovima i automobilima -- svaka od tih površina zahteva refleksiju. Tradicionalni pristup prosto ne skalira.

26.1.3 Tradicionalni pristupi i njihova ograničenja

Pre Lumena, Unreal Engine (i drugi engine-i) koristili su nekoliko trikova da simuliraju refleksije. Hajde da prođemo kroz svaki:

Reflection Capture Actors (Statički Cubemap-ovi)

Ovo je najstariji i najjeftiniji pristup:

  1. Postavite Reflection Capture Actor u scenu -- obično SphereReflectionCapture ili BoxReflectionCapture.
  2. Engine renderuje scenu iz pozicije tog aktora u šest pravaca (gore, dole, levo, desno, napred, nazad) i kreira cubemap -- teksturu koja pokriva svih 360 stepeni.
  3. Kada materijal treba refleksiju, uzima odgovarajući piksel iz najbližeg cubemap-a.

Prednosti:

Mane:

// Primer postavljanja Reflection Capture Actors u nivou
// (Blueprint ili ručno postavljanje u Editor-u)

// 1. Dodajte SphereReflectionCapture u scenu
//    - Podesite Influence Radius da pokrije željenu oblast
//    - Brightness: 1.0 (default)
//    - Cubemap Resolution: obično 256 ili 512

// 2. Za zatvorene prostore, koristite BoxReflectionCapture
//    - Box Extent: podesite da odgovara dimenzijama sobe
//    - Box Transition Distance: koliko blago se blenduje sa susednim capture-ovima

Planar Reflections

Za ravne reflektivne površine (podovi, voda, ogledala), Unreal nudi Planar Reflection sistem:

  1. Postavite PlanarReflectionComponent na ravnu površinu.
  2. Engine renderuje celu scenu ponovo, sa kamerom koja je odraz (mirror) stvarne kamere u odnosu na tu ravan.
  3. Rezultat se projicira nazad na površinu.

Prednosti:

Mane:

Screen-Space Reflections (SSR) -- Pre-Lumen verzija

SSR je post-processing efekat koji smo ukratko pomenuli u Poglavlju 15:

  1. Za svaki piksel na ekranu, izračunava reflektovani zrak na osnovu normale površine.
  2. Taj zrak marširate (ray march) kroz depth buffer -- provera piksela po piksel da li reflektovani zrak pogađa nešto što je već vidljivo na ekranu.
  3. Ako pogodi, koristite boju tog piksela kao refleksiju.

Prednosti:

Mane:

26.1.4 Lumen pristup: višeslojni sistem

Lumen rešava problem refleksija na elegantan način -- ne koristi samo jednu tehniku, već kombinuje više tehnika u slojevitom sistemu, gde svaki sloj pokriva slabosti prethodnog:

┌─────────────────────────────────────────────┐
│          LUMEN REFLECTION PIPELINE          │
├─────────────────────────────────────────────┤
│                                             │
│  Sloj 1: Screen-Space Reflections (SSR)     │
│  ├── Najjeftiniji                           │
│  ├── Koristi depth buffer                   │
│  ├── Radi za vidljive piksele               │
│  └── Ako ne pronađe rezultat ──┐            │
│                                │            │
│  Sloj 2: Surface Cache Trace   │◄───────────┘
│  ├── Koristi Lumen Surface Cache             │
│  ├── Radi za off-screen geometriju          │
│  ├── Niža rezolucija, ali potpun            │
│  └── Ako je HW RT uključen ───┐            │
│                                │            │
│  Sloj 3: Hardware Ray Tracing  │◄───────────┘
│  (opciono)                                  │
│  ├── Trace protiv pravih trouglova          │
│  ├── Najviši kvalitet                       │
│  ├── Najskuplji                             │
│  └── Za archviz, cinematics, hero momenti   │
│                                             │
│  Fallback: Reflection Captures              │
│  └── Statički cubemap-ovi kao poslednje     │
│      utočište                               │
│                                             │
└─────────────────────────────────────────────┘

Ova slojevita arhitektura je ključna inovacija. Umesto da se oslanjamo na jednu skupu tehniku za sve, Lumen inteligentno bira najjeftiniju tehniku koja može da pruži korektan rezultat za svaki piksel. Hajde da detaljno prođemo kroz svaki sloj.


26.2 Screen-Space Reflections (SSR) kao prvi sloj

26.2.1 Osnove SSR algoritma

Screen-Space Reflections su prva linija odbrane u Lumen reflection pipeline-u. Razlog je jednostavan: SSR je najjeftinija tehnika koja pruža dinamične refleksije. Nema potrebe za dodatnim renderovanjem scene, nema potrebe za ray tracing hardverom -- sve se radi na osnovu podataka koji su već dostupni nakon glavnog renderinga.

Hajde da detaljno prođemo kako SSR funkcioniše:

Korak 1: Prikupljanje podataka

Nakon što engine renderuje scenu, imamo na raspolaganju nekoliko buffer-a:

SSR koristi sve ove podatke.

Korak 2: Računanje reflektovanog zraka

Za svaki piksel na ekranu koji ima dovoljno nisku roughness vrednost da opravda reflection izračunavanje:

  1. Rekonstruišite 3D poziciju piksela koristeći depth buffer i inverznu projekcionu matricu.
  2. Izračunajte view direction -- vektor od kamere do tog piksela.
  3. Koristeći normalu površine iz normal buffer-a, izračunajte reflektovani vektor (reflect direction) primenom standardne formule:
R = V - 2 * dot(V, N) * N

gde je:
  V = view direction (od površine ka kameri, normalizovan)
  N = normala površine (normalizovana)
  R = reflektovani pravac

Sada imamo zrak koji počinje od površine piksela i ide u pravcu refleksije.

Korak 3: Ray Marching kroz Depth Buffer

Ovo je srce SSR algoritma. Uzimamo reflektovani zrak i "maršujemo" ga kroz prostor, ali umesto da proverimo da li pogađa pravu geometriju (što bi zahtevalo ray tracing), radimo nešto pametnije:

  1. Projektujte zrak nazad na ekran. Reflektovani zrak koji ide kroz 3D prostor će, kada se projektuje na 2D ekran, formirati liniju na ekranu.
  2. Koračajte duž te linije, piksel po piksel (ili sa nekim korakom, step size).
  3. Za svaki korak, proverite: da li je dubina na toj poziciji ekrana bliža kameri od dubine našeg zraka? Ako jeste, to znači da je zrak "prošao iza" nečega -- pronašli smo pogodak (intersection).
// Pseudo-kod SSR ray marching algoritma

for (int step = 0; step < MaxSteps; step++)
{
    // Izračunaj poziciju zraka u ovom koraku
    float3 RayPosition = StartPos + ReflectionDir * step * StepSize;
    
    // Projektuj nazad na ekran (screen space)
    float2 ScreenUV = ProjectToScreen(RayPosition);
    
    // Ako smo izašli sa ekrana, prekini
    if (ScreenUV.x < 0 || ScreenUV.x > 1 || 
        ScreenUV.y < 0 || ScreenUV.y > 1)
    {
        // SSR FAIL - zrak je napustio ekran
        break;
    }
    
    // Pročitaj dubinu scene na toj poziciji ekrana
    float SceneDepth = DepthBuffer.Sample(ScreenUV);
    float RayDepth = GetDepth(RayPosition);
    
    // Da li je zrak "prošao iza" geometrije?
    if (RayDepth > SceneDepth)
    {
        // POGODAK! Koristimo boju na toj poziciji ekrana
        float3 ReflectionColor = ColorBuffer.Sample(ScreenUV);
        return ReflectionColor;
    }
}

// Nismo ništa pronašli - SSR FAIL
return SSR_MISS;

Korak 4: Refinement (opciono)

Kada detektujemo pogodak, obično nije tačan na nivou piksela jer koračamo sa nekim step size-om. Mnoge SSR implementacije koriste binary search refinement: kada detektujete pogodak, vratite se pola koraka nazad i proverite ponovo, zatim pola od toga, itd. Ovo omogućava preciznije nalaženje tačke preseka sa znatno manje koraka.

// Binary search refinement
float3 HitPos = LastPosition;
for (int i = 0; i < RefinementSteps; i++)
{
    float3 MidPoint = lerp(PreviousPosition, HitPos, 0.5);
    float2 MidUV = ProjectToScreen(MidPoint);
    float MidSceneDepth = DepthBuffer.Sample(MidUV);
    float MidRayDepth = GetDepth(MidPoint);
    
    if (MidRayDepth > MidSceneDepth)
        HitPos = MidPoint;      // Pogodak je bliže
    else
        PreviousPosition = MidPoint;  // Pogodak je dalje
}

26.2.2 Zašto je SSR "najjeftiniji"

SSR je relativno jeftin iz nekoliko razloga:

  1. Nema dodatnog renderovanja scene. Koristi podatke koji su već izračunati (color, depth, normal buffer-i).
  2. Radi u screen space. Umesto da obrađuje milione trouglova, radi samo sa pikselima na ekranu -- tipično 1920x1080 ili 3840x2160, što je mnogo manje od broja trouglova u sceni.
  3. Može se ograničiti. Broj koraka (steps) i dužina zraka (ray length) se mogu kontrolisati, što direktno utiče na performanse.
  4. Rough površine ne zahtevaju SSR. Za piksele sa visokim roughness-om, SSR se uopšte ne izvršava jer bi refleksija bila toliko zamućena da je GI pokriva.

26.2.3 Ograničenja SSR-a -- zašto sam nije dovoljan

Koliko god da je SSR pametan, ima fundamentalna ograničenja koja proizlaze iz toga što radi isključivo u screen space:

Problem 1: Off-screen sadržaj

SSR može reflektovati samo ono što kamera vidi. Ako stojite pored ogledala i gledate u njega, ogledalo bi trebalo da pokaže ono što je iza vas -- ali kamera to ne vidi, pa toga nema u color buffer-u. SSR u tom slučaju ne može da pruži rezultat.

     Kamera
       │
       │  (kamera vidi ispred)
       ▼
    ┌──────────┐
    │          │
    │ OGLEDALO │ ← Treba da reflektuje ono što je iza kamere
    │          │    Ali SSR ima samo piksele ispred kamere!
    └──────────┘
       │
       │  (iza kamere - NEVIDLJIVO za SSR)
       ▼
    ┌──────────┐
    │ OBJEKAT  │ ← Ovaj objekat ne postoji u screen space
    └──────────┘

Problem 2: Ivice ekrana

Čak i za sadržaj koji jeste na ekranu, refleksije blizu ivica ekrana su problematične. Reflektovani zrak može brzo napustiti vidljivi deo ekrana, ostavljajući deo refleksije prazan.

Problem 3: Samo prednji deo

Depth buffer sadrži samo prvu površinu koja je vidljiva kameri. Ako objekat zaklanja drugi objekat, SSR ne može reflektovati zaklonjeni objekat -- ne postoji u depth buffer-u.

Problem 4: Tanki objekti i mali detalji

Kada ray marching korača sa velikim step size-om (radi performansi), može "preskočiti" tanke objekte. Na primer, ograda ili stub od fenjera mogu biti potpuno promašeni.

26.2.4 SSR u kontekstu Lumena

U Lumen pipeline-u, SSR je prvi pokušaj. Za svaki piksel koji zahteva refleksiju:

  1. Probaj SSR.
  2. Ako SSR pronađe pogodak -- koristi ga. Gotovo. Jeftino i kvalitetno.
  3. Ako SSR ne pronađe pogodak (zrak izašao sa ekrana, ništa nije pogodio, itd.) -- prosledi dalje, na sledeći sloj (Surface Cache trace).

Ovo znači da za mnoge piksele -- posebno one gde refleksija pokazuje nešto što je vidljivo na ekranu -- dobijate visokokvalitetnu refleksiju za minimalnu cenu. Surface Cache se aktivira samo tamo gde je SSR zakazao.

Podešavanja SSR-a u Lumen kontekstu:

// Console variables relevantne za SSR sloj u Lumen refleksijama:

r.Lumen.Reflections.ScreenTraces    // 1 = SSR uključen (default), 0 = isključen
r.Lumen.Reflections.ScreenTraceMaxRoughness  // Max roughness za SSR (default ~0.4)

Savet: Nemojte isključivati SSR sloj osim ako imate vrlo specifičan razlog. SSR je najjeftiniji deo pipeline-a i pokriva značajan procenat piksela, čime smanjuje opterećenje na skuplje Surface Cache i HW RT slojeve.


26.3 Surface Cache Fallback

26.3.1 Šta je Surface Cache -- kratki podsetnik

U Poglavlju 25 smo detaljno obradili kako Lumen gradi i održava Surface Cache -- ubrzanu reprezentaciju scene koja je mnogo jeftinija za ray tracing od pune geometrije. Hajde da se kratko podsetimo:

Surface Cache je sistem gde Lumen:

  1. Konvertuje svaki mesh u sceni u Mesh Cards -- ravne "kartice" koje aproksimiraju površine mesh-a.
  2. Na te kartice renderuje (ili "cache-ira") materijal properties -- boju (albedo), normalu, emissive vrednost, i drugo.
  3. Organizuje ove podatke u hijerarhijsku strukturu koja omogućava brzo ray tracing.

Ključna stvar: Surface Cache sadrži informacije o celoj sceni, ne samo o onome što kamera vidi. To je fundamentalna razlika u odnosu na SSR.

26.3.2 Kako Surface Cache rešava SSR probleme

Kada SSR zakaže za određeni piksel -- recimo, reflektovani zrak izlazi sa ekrana -- Lumen prelazi na tracing zraka protiv Surface Cache-a:

  1. Isti reflektovani zrak koji je SSR pokušao da prati se sada koristi za trace protiv Surface Cache-a.
  2. Ray trace prolazi kroz Lumen Scene strukturu (globalna reprezentacija scene koristeći Signed Distance Fields ili mesh cards).
  3. Kada zrak pogodi nešto u Surface Cache-u, čita se cache-irana boja te površine.
// Konceptualni tok za svaki piksel koji zahteva refleksiju:

ReflectionColor = TrySSR(ReflectionRay);

if (ReflectionColor == SSR_MISS)
{
    // SSR nije pronašao ništa -- pokušaj Surface Cache
    SurfaceCacheHit = TraceSurfaceCache(ReflectionRay);
    
    if (SurfaceCacheHit.IsValid)
    {
        ReflectionColor = SurfaceCacheHit.CachedColor;
    }
    else
    {
        // Čak ni Surface Cache nije pogodio ništa
        // (npr. zrak ide u nebo)
        ReflectionColor = SkyLightColor; // ili Reflection Capture fallback
    }
}

26.3.3 Kvalitet Surface Cache refleksija

Surface Cache refleksije su niže rezolucije od SSR-a, i postoji dobar razlog za to:

Razlika u kvalitetu

Zašto je to prihvatljivo

U praksi, ova razlika u kvalitetu je retko primetna, iz dva razloga:

  1. Surface Cache se koristi samo tamo gde SSR zakaže. To su obično delovi refleksije koji su daleko od kamere ili prikazuju sadržaj koji je van ekrana -- a ljudsko oko je manje osetljivo na kvalitet tih delova.
  2. Temporal accumulation (temporalno akumuliranje) sakuplja podatke iz više frejmova i rezultat je stabilniji i kvalitetniji nego što bi bio iz jednog frejma.

26.3.4 Multi-resolution Surface Cache

Lumen Surface Cache koristi višerezolucionsku strukturu, što je ključno za balansiranje kvaliteta i performansi:

Nivo 1: Detaljni Surface Cache (blizu kamere)

Za mesh-eve koji su blizu kamere, Surface Cache ima višu rezoluciju Mesh Cards-a. Ovo znači:

Nivo 2: Srednji Surface Cache

Za mesh-eve na srednjoj udaljenosti:

Nivo 3: Udaljeni Surface Cache (daleko od kamere)

Za udaljene objekte:

// Vizualizacija multi-resolution Surface Cache-a:

Blizu kamere         Srednja udaljenost      Daleko
┌────────────────┐   ┌──────────┐            ┌────┐
│ ┌──┐ ┌──┐ ┌──┐│   │ ┌──┐┌──┐ │            │    │
│ │  │ │  │ │  ││   │ │  ││  │ │            │    │
│ └──┘ └──┘ └──┘│   │ └──┘└──┘ │            │    │
│ ┌──┐ ┌──┐ ┌──┐│   │ ┌──┐┌──┐ │            │    │
│ │  │ │  │ │  ││   │ │  ││  │ │            └────┘
│ └──┘ └──┘ └──┘│   │ └──┘└──┘ │         1 kartica,
│16 kartica,     │   │4 kartice, │         niska rez.
│visoka rez.     │   │sred. rez. │
└────────────────┘   └──────────┘

Kako ovo utiče na refleksije

Kada reflektovani zrak pogodi objekat koji je blizu kamere, Surface Cache pruža relativno detaljnu informaciju -- refleksija izgleda dobro. Kada zrak pogodi udaljeni objekat, informacija je grublja, ali to je prihvatljivo jer bi i same refleksije udaljenih objekata bile male i nedetaljne.

Ovaj multi-resolution pristup omogućava Lumenu da pokrije celu scenu za refleksije bez eksplozije u memorijskom ili compute budžetu.

26.3.5 Ograničenja Surface Cache refleksija

Iako Surface Cache rešava glavni problem SSR-a (off-screen sadržaj), ima svoja ograničenja:

  1. Rezolucija. Kao što smo pomenuli, Surface Cache refleksije su niže rezolucije. Za scenu sa ogledalom gde gledate sopstveni odraz, ovo može biti primetno.

  2. Mesh Cards pokrivanje. Nije svaka površina mesh-a savršeno pokrivena karticama. Komplikovani mesh-evi (npr. gusto lišće) mogu imati praznine u Surface Cache-u, što dovodi do artefakata u refleksijama.

  3. Ažuriranje kašnjenja. Surface Cache se ažurira postepeno, frame po frame. Ako se scena naglo promeni (eksplozija, naglo otvaranje vrata), može proći nekoliko frejmova pre nego što se promene reflektuju u Surface Cache-u i, samim tim, u refleksijama.

  4. Nedostatak finih geometrijskih detalja. Surface Cache aproksimira geometriju karticama. Sitni detalji -- ivice, mali objekti, tanke strukture -- mogu biti izgubljeni.

Za mnoge scene, ova ograničenja su prihvatljiva. Ali za situacije gde je kvalitet refleksija kritičan, postoji treći sloj: Hardware Ray Tracing.

26.3.6 Vizualizacija Surface Cache-a u editoru

Unreal Engine pruža alate za vizualizaciju Surface Cache-a, što je korisno za debugging:

// U Editor-u: View Mode > Lumen > Surface Cache

// Ili koristite console komande:
r.Lumen.Visualize.CardPlacement 1    // Prikaži mesh cards
r.Lumen.Visualize.SurfaceCache 1     // Prikaži surface cache sadržaj

Kada uključite vizualizaciju, videćete kako su mesh-evi pokriveni karticama i kakav je kvalitet cache-iranih podataka. Ovo je izuzetno korisno kada primetite artefakte u refleksijama -- često je uzrok loše pokrivanje Surface Cache-a za taj mesh.

Praktičan savet: Ako primetite da određeni mesh ima lošu refleksiju kada se prikazuje kroz Surface Cache, proverite da li mesh ima dovoljno Mesh Cards-a. U Static Mesh Editor-u, pod Lumen sekcijom, možete podesiti Max Lumen Mesh Cards za taj mesh. Povećanje broja može pomoći, ali i povećava memorijski otisak.


26.4 Hardware Ray Traced (HW RT) refleksije

26.4.1 Šta su Hardware RT refleksije

Hardware Ray Traced refleksije predstavljaju najviši kvalitet refleksija dostupan u Lumen-u. Umesto da koriste Surface Cache (aproksimaciju scene), HW RT refleksije koriste pravu geometriju scene -- tačne trouglove -- za ray tracing.

Moderni GPU-ovi (NVIDIA RTX serija, AMD sa RDNA 2+) imaju dedicirane hardverske jedinice za ray tracing -- RT cores (NVIDIA) ili Ray Accelerators (AMD). Ove jedinice mogu izuzetno brzo pronaći presek zraka sa trouglovskom geometrijom, koristeći hardverski akceleriranu BVH (Bounding Volume Hierarchy) strukturu.

26.4.2 Kako HW RT refleksije rade

Tok je sledeći:

  1. Priprema Acceleration Structure. Engine gradi BLAS (Bottom Level Acceleration Structure) za svaki mesh i TLAS (Top Level Acceleration Structure) za celu scenu. Ovo je hijerarhijska struktura kutija (bounding volumes) koja omogućava brzo pronalaženje preseka zraka sa trouglovima.

  2. Reflection ray dispatch. Za svaki piksel koji zahteva refleksiju (i gde SSR nije dao rezultat), engine šalje ray trace zahtev hardveru.

  3. Hardverski trace. RT cores prolaze kroz TLAS i BLAS, pronalaze tačan trougao koji zrak pogađa.

  4. Material evaluation. Na mestu pogotka, engine evaluira materijal -- čita teksture, izračunava boju, normalu, roughness, itd. Ovo se zove hit shader ili closest hit shader u DXR/Vulkan RT terminologiji.

  5. Rezultat. Boja refleksije se vraća nazad i kombinuje sa ostalim podacima za finalni piksel.

// Konceptualni pseudo-kod za HW RT reflection

RayDesc ray;
ray.Origin = WorldPosition;        // Pozicija piksela u svetu
ray.Direction = ReflectionDir;     // Reflektovani pravac
ray.TMin = 0.001;                  // Minimalna udaljenost (izbegavanje self-intersection)
ray.TMax = MaxTraceDistance;       // Maksimalna udaljenost trace-a

RayTraceResult result = TraceRay(
    TLAS,                          // Top Level Acceleration Structure
    ray,
    RAY_FLAG_NONE
);

if (result.Hit)
{
    // Evaluiraj materijal na mestu pogotka
    float3 HitColor = EvaluateMaterial(result.HitTriangle, result.UV);
    
    // Opciono: prikupi i osvetljenje na mestu pogotka
    float3 HitLighting = SampleLightingAtHitPoint(result.WorldPosition);
    
    ReflectionColor = HitColor * HitLighting;
}
else
{
    ReflectionColor = SkyColor;
}

26.4.3 Prednosti HW RT refleksija

Tačnost geometrije

Najveća prednost HW RT-a je tačnost. Dok Surface Cache aproksimira geometriju karticama (i time gubi fine detalje), HW RT radi sa pravim trouglovima. Ovo znači:

Dinamičnost

HW RT TLAS se ažurira svakog frejma, što znači da pokretni objekti (likovi, vozila, animirani objekti) mogu biti tačno reflektovani.

Kvalitet za zahtevne scenarije

Za archviz (arhitektonsku vizualizaciju), filmske sekvence (cinematics), ili "hero momente" u igrama (cutscene sa bliskim kadrom na reflektivnu površinu), HW RT refleksije pružaju kvalitet koji je teško razlikovati od offline renderinga.

26.4.4 Cena HW RT refleksija

Nemojmo se zavaravati -- HW RT refleksije su skupe. Evo zašto:

  1. Ray trace je inherentno skuplji od rasterizacije. Pronalaženje preseka zraka sa milionima trouglova, čak i sa hardverskom akceleracijom, zahteva značajan compute budget.

  2. Material evaluation na hit poziciji. Za svaki pogodak, engine mora da pročita teksture i izračuna boju -- ovo zahteva bandwidth i compute.

  3. Šum i denoising. Sa ograničenim brojem zraka po pikselu (obično 1 za refleksije), rezultat je šumljiv. Potreban je denoiser koji dodaje svoj compute budžet.

  4. Memorija za Acceleration Structure. BLAS i TLAS zauzimaju VRAM. Za scenu sa milionima trouglova, ovo može biti stotine MB dodatne memorije.

  5. TLAS ažuriranje. Svaki frame, TLAS mora biti ažuriran za pokretne objekte -- dodatni GPU compute.

26.4.5 Kada koristiti HW RT refleksije

S obzirom na cenu, HW RT refleksije imaju smisla u sledećim scenarijima:

Archviz (Arhitektonska vizualizacija)

Klijenti očekuju fotorealistične rendere. Ogledala, mermerni podovi, staklene površine -- sve mora biti savršeno. Performanse (frame rate) nisu primarni cilj jer se često radi o interaktivnom pregledu (ne igri), pa je 30 FPS prihvatljivo.

// Preporučena podešavanja za Archviz:
r.Lumen.Reflections.HardwareRayTracing 1
r.Lumen.Reflections.HardwareRayTracing.Quality 1  // Visok kvalitet
r.RayTracing.Reflections.MaxRoughness 0.6
r.RayTracing.Reflections.MaxBounces 2  // Refleksija refleksije (ogledalo u ogledalu)

Cinematics (Filmske sekvence)

Za pre-renderovane ili real-time cutscene gde je kvalitet priče i vizuelnog doživljaja prioritet. Frame rate je fiksiran i kontrolisan, pa je budget za refleksije poznat unapred.

Hero momenti u igrama

Ponekad u igri imate ključnu scenu -- igrač stoji u galeriji okruženoj ogledalima, ili gleda refleksiju u vodi tokom dramatičnog momenta. Za takve scene, možete privremeno uključiti HW RT refleksije i vratiti se na Surface Cache za ostatak igre.

// Primer: Uključivanje HW RT refleksija za specifičnu scenu
// (u Blueprint-u ili C++ kodu)

void AMyLevelScript::OnPlayerEnterMirrorRoom()
{
    // Uključi HW RT refleksije
    GEngine->Exec(GetWorld(), TEXT("r.Lumen.Reflections.HardwareRayTracing 1"));
}

void AMyLevelScript::OnPlayerLeaveMirrorRoom()
{
    // Vrati na Software tracing
    GEngine->Exec(GetWorld(), TEXT("r.Lumen.Reflections.HardwareRayTracing 0"));
}

Platforme sa snažnim GPU-ovima

Za projekte koji ciljaju PC sa high-end GPU-ovima (RTX 3080+, RX 6800 XT+) ili PS5/Xbox Series X gde je RT podržan, HW RT refleksije mogu biti izvodljive čak i za gameplay.

26.4.6 Software vs Hardware Ray Tracing za refleksije

Važno je razumeti razliku između dva režima Lumen refleksija:

Karakteristika Software RT (Surface Cache) Hardware RT
Zahteva RT hardver Ne Da (RTX, RDNA 2+)
Podaci za trace Mesh Cards / SDF Pravi trouglovi (BVH)
Kvalitet geometrije Aproksimacija Tačna geometrija
Mali detalji Mogu biti izgubljeni Vidljivi
Performanse Brže Sporije
Memorija Manja Veća (BVH strukture)
Preporučeno za Igre, real-time aplikacije Archviz, cinematics, hero momenti

26.4.7 Hibridni pristup: SSR + HW RT

U praksi, čak i kada koristite HW RT refleksije, SSR ostaje prvi sloj. Tok je:

  1. SSR -- probaj prvo (najjeftinije).
  2. HW RT -- ako SSR promaši, koristi HW RT umesto Surface Cache tracing-a.
  3. Reflection Captures -- poslednji fallback.

Ovo znači da HW RT ne mora da trace-uje zrake za piksele gde je SSR već dao rezultat, čime se značajno smanjuje ukupan broj RT zraka i poboljšavaju performanse.


26.5 Reflection Captures vs Lumen Reflections

26.5.1 Legacy sistem: Reflection Capture Actors

Pre Lumena, Reflection Capture Actors su bili primarni sistem za refleksije u Unreal Engine-u. Već smo ih kratko opisali u sekciji 26.1.3, ali hajde da detaljnije pogledamo kako funkcionišu i kakvu ulogu imaju u Lumen eri.

Tipovi Reflection Capture Actors

  1. SphereReflectionCapture

    • Pokriva sfernu oblast definisanu radijusom (Influence Radius).
    • Blenduje se sa susednim capture-ovima na osnovu udaljenosti.
    • Najčešće korišćen tip.
  2. BoxReflectionCapture

    • Pokriva pravougaonu oblast (box extent).
    • Idealan za zatvorene prostore (sobe, hodnici).
    • Može koristiti Box Projection za korekciju parallax error-a unutar prostorije.

Kako se cubemap generiše

Kada izgradite osvetljenje (Build Lighting) ili kada se nivo učita:

  1. Engine postavlja virtualnu kameru na poziciju Reflection Capture aktora.
  2. Renderuje scenu u šest pravaca: +X, -X, +Y, -Y, +Z, -Z.
  3. Rezultat je cubemap (šest slika koje pokrivaju 360 stepeni).
  4. Cubemap se filtrira za različite roughness nivoe (pre-filtered environment map), kreirajući mipmap lanac gde viši mip nivoi odgovaraju grubljim površinama.
// Vizualizacija cubemap mipmapa za različite roughness vrednosti:

Roughness 0.0    Roughness 0.2    Roughness 0.5    Roughness 0.8
(Mip 0)          (Mip 2)          (Mip 4)          (Mip 6)
┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│ ▓▒░▓▒░▓▒ │     │ ▓▒▒▓▒▒▓▒ │     │ ▒▒▒▒▒▒▒▒ │     │ ░░░░░░░░ │
│ ▒▓░▒▓░▒▓ │     │ ▒▓▒▒▓▒▒▓ │     │ ▒▒▒▒▒▒▒▒ │     │ ░░░░░░░░ │
│ ░▒▓░▒▓░▒ │     │ ▒▒▓▒▒▓▒▒ │     │ ▒▒▒▒▒▒▒▒ │     │ ░░░░░░░░ │
│ (oštra)   │     │ (blago   │     │ (zamućena)│     │ (veoma   │
│           │     │  zamućena)│     │           │     │  zamućena)│
└──────────┘     └──────────┘     └──────────┘     └──────────┘

26.5.2 Reflection Captures u Lumen eri

Sa Lumenom, Reflection Capture Actors više nisu primarni sistem za refleksije. Lumen ih zamenjuje dinamičkim, tačnijim refleksijama. Ali to ne znači da su potpuno zastareli -- imaju specifične uloge:

Uloga 1: Poslednji fallback

U Lumen reflection pipeline-u, Reflection Captures služe kao poslednji sloj: kada ni SSR ni Surface Cache (ni HW RT) ne pronađu pogodak za reflektovani zrak -- recimo, zrak ide prema nebu a SkyLight nije podešen -- Reflection Capture cubemap može pružiti osnovnu refleksiju.

Uloga 2: Performansna alternativa

Za manje važne površine ili za projekte sa strožim performansnim budžetom, možete konfigurisati određene materijale ili oblasti da koriste Reflection Captures umesto Lumen refleksija. Ovo je korisno za:

Uloga 3: Kontrola umetnika

Ponekad umetnik želi ručnu kontrolu nad tim kako refleksija izgleda. Sa Reflection Capture Actors, možete:

26.5.3 Konfiguracija: Lumen vs Captures

U Project Settings > Engine > Rendering > Reflections:

// Reflection Method opcije:

- None               // Bez refleksija
- Lumen              // Lumen reflection pipeline (preporučeno za UE5)
- Screen Space       // Samo SSR (legacy, bez Surface Cache)
- Reflection Captures // Samo statički cubemap-ovi (legacy)

Kada je Lumen odabran, Reflection Capture Actors i dalje rade kao fallback, ali Lumen je primarni sistem.

26.5.4 Postavljanje Reflection Captures za Lumen fallback

Čak i kada koristite Lumen refleksije, dobra praksa je postaviti Reflection Capture Actors kao fallback:

// Preporuke za postavljanje:

1. Stavite barem jedan SphereReflectionCapture u svaku 
   zatvorenu prostoriju.

2. Za otvorene prostore, koristite SkyLight sa Cubemap-om
   (on implicitno služi kao "globalni" reflection fallback).

3. Za sobe sa specifičnim osvetljenjem, podesite Brightness
   na Reflection Capture aktoru da odgovara ambijentu.

4. Ne preterujte sa brojem capture aktora -- u Lumen modu,
   oni se koriste retko, pa 1-2 po prostoriji je dovoljno.

26.5.5 Mešanje Lumen-a i Captures-a u istoj sceni

Postoje scenariji gde želite da određeni materijali koriste Reflection Captures umesto Lumena:

U Material Editor-u, možete koristiti Reflection Capture node ili kontrolisati ponašanje preko material properties. Međutim, u praksi, ovo je retko potrebno -- Lumen reflection pipeline automatski bira najoptimalniju tehniku za svaki piksel.

Napomena: Ako ste prethodno radili sa UE4 ili ranijim verzijama UE5 bez Lumena, možda imate scenu sa velikim brojem pažljivo postavljenih Reflection Capture Actors. Kada prebacite na Lumen refleksije, te capture aktore ne morate uklanjati -- oni će jednostavno postati manje korišćeni fallback. Ali možete smanjiti njihov broj i rezoluciju radi uštede memorije.


26.6 Roughness i uticaj na cenu refleksija

26.6.1 Roughness kao ključni parametar

U Poglavlju 11 detaljno smo obradili PBR materijale i roughness parametar. Sada ćemo pogledati kako roughness dramatično utiče na cenu i kvalitet refleksija u Lumen-u.

Podsetnik: roughness kontroliše koliko su mikro-površine materijala neravne, što direktno utiče na to koliko su refleksije oštre ili zamućene:

Roughness 0.0          Roughness 0.3          Roughness 0.6
┌──────────────┐       ┌──────────────┐       ┌──────────────┐
│   ╔══════╗   │       │   ╔══════╗   │       │              │
│   ║Mirror║   │       │   ║Blurry║   │       │   (diffuse   │
│   ║Image ║   │       │   ║Image ║   │       │    lighting) │
│   ╚══════╝   │       │   ╚══════╝   │       │              │
│  Chrome/     │       │  Polished    │       │  Concrete/   │
│  Water       │       │  Metal       │       │  Rough       │
│              │       │              │       │  Plastic     │
└──────────────┘       └──────────────┘       └──────────────┘

26.6.2 Savršeno glatke površine (Roughness 0 -- 0.1): Oštre refleksije

Površine sa roughness bliskim nuli se ponašaju kao ogledala. Refleksija je oštra, jasna i direktna.

Prednosti za rendering:

Izazovi za rendering:

// Primer: Materijal za ogledalo u UE5

// Material Properties:
//   Base Color: (0.9, 0.9, 0.9) -- gotovo beo (ogledalo reflektuje skoro svu svetlost)
//   Metallic: 1.0
//   Roughness: 0.0 -- savršeno glatko
//   Specular: 0.5 (default)

// Ovaj materijal će koristiti:
// 1. SSR ako refleksija pogodi nešto na ekranu
// 2. Surface Cache ili HW RT za off-screen sadržaj
// 3. Reflection Capture kao poslednji fallback

26.6.3 Umereno glatke površine (Roughness 0.1 -- 0.4): Zamućene refleksije

Ovo je "sweet spot" koji je najizazovniji za rendering. Površine poput poliranog metala, lakiranih podova, ili mokrog asfalta spadaju u ovu kategoriju.

Zašto je ovo skupo

Zamućena refleksija nastaje jer mikro-površina rasejava svetlost u konus umesto u jednom pravcu. Da biste izračunali zamućenu refleksiju, morate uzorkovati više pravaca unutar tog konusa:

// Za roughness = 0.0 (ogledalo):
// Samo 1 pravac refleksije

       │ Normala
       │
   ────┼────  Površina
      ╱│
     ╱ │
    ╱  │
   ╱   │  ← 1 reflektovani zrak
  ╱    │


// Za roughness = 0.3 (zamućena refleksija):
// Konus reflektovanih pravaca

         │ Normala
         │
   ──────┼──────  Površina
       ╱╱│
      ╱╱╱│
     ╱╱╱╱│
    ╱╱╱╱╱│  ← Konus zraka (treba mnogo uzoraka!)
   ╱╱╱╱╱╱│

Više zraka = bolja aproksimacija zamućene refleksije, ali i veća cena.

Sa samo 1 zrakom po pikselu u konus, rezultat je veoma šumljiv (noisy) -- svaki piksel pogodi različit deo konusa i dobija različitu boju. Denoiser mora da "poravna" ove rezultate, što funkcioniše, ali zahteva temporalno akumuliranje (korišćenje podataka iz prethodnih frejmova) i može dovesti do "ghosting" artefakata na pokretnim objektima.

Kompromis: Roughness i rezolucija tracing-a

Lumen koristi pametan trik: za grulje površine, reflection tracing se radi na nižoj rezoluciji. Logika je sledeća:

Roughness     Trace rezolucija     Broj zraka     Denoising
──────────────────────────────────────────────────────────────
0.0 - 0.1     Puna                 1/piksel        Minimalan
0.1 - 0.3     Puna do 1/2          1/piksel        Umeren
0.3 - 0.5     1/2 do 1/4           1/piksel        Jak
0.5 - 0.8     1/4                  1/piksel        Veoma jak
0.8+          Nema (GI pokriva)    0               N/A

26.6.4 Grube površine (Roughness 0.5 -- 0.8): Između refleksije i GI

Za roughness vrednosti između 0.5 i 0.8, refleksije su toliko zamućene da su na granici između specular refleksije i diffuse osvetljenja. Lumen u ovom opsegu kombinuje reflection trace sa GI podatcima:

Ovo je efikasno jer GI sistem (koji koristi radiance cache i probe-ove) je dizajniran za zamućene efekte i već pokriva većinu informacija za grube površine.

26.6.5 Veoma grube površine (Roughness 0.8+): GI preuzima

Za roughness 0.8 i više, refleksije su praktično nevidljive kao zasebni efekti. Ono što vidimo je samo opšte indirektno osvetljenje -- difuzni odsjaj okoline. U ovom režimu, Lumen reflection system ne troši resurse -- GI system iz Poglavlja 25 potpuno preuzima:

// Lumen automatski ne trace-uje reflection zrake za piksele 
// sa roughness > MaxReflectionRoughness

// Ovo se kontroliše sa:
r.Lumen.Reflections.MaxRoughness  // Default: ~0.8

26.6.6 Performansne implikacije: Scene sa mnogo glatkih površina

Ovo je kritična informacija za dizajn nivoa i materijala:

Scene sa mnogo glatkih, reflektivnih površina su SKUPLJE za renderovanje.

Razmotrimo dva scenarija:

Scenario A: Rustikalna soba

Scenario B: Moderni lobi

// Performansna razlika u praksi:

Scenario A (rustikalna soba):
  SSR: ~5% piksela zahteva trace
  Surface Cache: ~2% piksela
  HW RT: N/A
  Ukupna reflection cena: ~0.5ms

Scenario B (moderni lobi):
  SSR: ~40% piksela zahteva trace
  Surface Cache: ~30% piksela
  HW RT: ~30% piksela (ako je uključen)
  Ukupna reflection cena: ~3-5ms

// Razlika: 6-10x skuplje!

Savet za dizajn nivoa: Ako imate performansni budžet od 16.6ms (60 FPS) i refleksije zauzimaju 5ms, to je skoro trećina vašeg budžeta! Razmislite o tome koliko reflektivnih površina zaista mora da bude u kadru istovremeno. Strateško korišćenje roughness-a može dramatično poboljšati performanse bez vidljivog gubitka kvaliteta.

26.6.7 Praktični saveti za roughness i refleksije

  1. Izbegavajte roughness = 0 osim ako zaista trebate ogledalo. Roughness od 0.05-0.1 i dalje izgleda veoma reflektivno, ali je znatno jeftinije za denoising.

  2. Koristite roughness varijaciju. Umesto da ceo pod ima roughness 0.1, koristite roughness mapu sa varijacijom 0.08-0.15. Ovo izgleda realističnije i pomaže denoiser-u.

  3. Razbijte velike reflektivne površine. Umesto jednog ogromnog mermernog poda, dodajte fugne (grout lines) sa višim roughness-om. Ovo smanjuje broj piksela koji zahtevaju trace.

  4. Testirajte sa Stat GPU komandom. Koristite Stat GPU u editoru da vidite koliko vremena troše refleksije. Ako je Reflections red dominantan, imate previše glatkih površina.

  5. Koristite dithered roughness oprezno. Neki materijali koriste dithering na roughness granici (npr. mokri/suvi delovi), što može dovesti do šumovitih refleksija. Razmislite o blažim prelazima.


26.7 Podešavanja kvaliteta refleksija i optimizacija

26.7.1 Pregled ključnih podešavanja

Lumen refleksije nude niz podešavanja za balansiranje kvaliteta i performansi. Ova podešavanja su dostupna kroz Project Settings, Post Process Volumes, i console komande.

Project Settings > Rendering > Lumen

// Osnovna podešavanja:

Reflection Method: Lumen           // Odaberite Lumen (ne Screen Space ili None)

// Hardware Ray Tracing:
Use Hardware Ray Tracing when available: true/false
  // Omogućava HW RT za Lumen (i GI i refleksije)

Lumen Reflections Quality: 
  // High, Medium, Low -- kontroliše default kvalitet

Post Process Volume podešavanja

// U Post Process Volume > Lumen Reflections:

Lumen Reflection Quality: 1.0
  // Skalira kvalitet refleksija u ovom volume-u
  // 0.5 = pola kvaliteta, 2.0 = dvostruki kvalitet
  // Direktno utiče na ray count i rezoluciju

Reflection Method: Lumen (ili override)
  // Može override-ovati globalno podešavanje za ovaj volume

26.7.2 Broj zraka po pikselu (Ray Count)

Broj zraka po pikselu je jedan od najvažnijih parametara za kvalitet i performanse refleksija.

Šta znači "više zraka"

Za svaki piksel koji zahteva refleksiju, engine pošalje jedan ili više zraka u reflektovanom smeru (sa ili bez varijacije za roughness). Više zraka = manje šuma = bolji kvalitet, ali i veća cena.

// Console variable za kontrolu ray count-a:
r.Lumen.Reflections.TracesPerPixel
  // Default: 1
  // Za veći kvalitet: 2-4
  // Za niže performanse: 1

// Napomena: Ovo se interno modulira sa roughness-om i 
// Lumen Reflection Quality skaliraom iz Post Process Volume-a.

Koliko zraka je dovoljno?

Scenario Preporučen ray count Objašnjenje
Igra (60 FPS target) 1 Temporal accumulation kompenzuje
Igra (30 FPS target) 1-2 Više budžeta, bolji kvalitet
Archviz (interaktivno) 2-4 Kvalitet je prioritet
Cinematics (offline) 4+ Maksimalni kvalitet

26.7.3 Temporal Accumulation i Denoising

Temporal accumulation je ključna tehnika koja omogućava Lumenu da pruži visokokvalitetne refleksije sa samo 1 zrakom po pikselu.

Kako radi

Umesto da šalje mnogo zraka u jednom frejmu, Lumen šalje 1 zrak po pikselu, ali svaki frame koristi drugačiji uzorak (jittered sample). Tokom vremena (5-20 frejmova), ovi uzorci se akumuliraju i prosečuju, dajući rezultat ekvivalentan slanju mnogo zraka u jednom frejmu.

// Vizualizacija temporal accumulation:

Frame 1: 1 zrak ─────────────────── šumljiv rezultat
Frame 2: 1 zrak (drugačiji uzorak) ─ šumljiv, ali drugačije
Frame 3: 1 zrak (opet drugačiji) ── šumljiv
Frame 4: 1 zrak ──────────────────── šumljiv
...
Akumulirano (Frame 1-4): ──────────── znatno čistiji rezultat!

Frame N (posle dovoljno akumulacije): gotovo čist rezultat

Problemi temporal accumulation

  1. Ghosting. Kada se objekat pomeri, stari akumulirani podaci "zaostaju" na staroj poziciji, stvarajući "duh" (ghost) koji polako nestaje. Lumen koristi motion rejection da ublaži ovo, ali neki ghosting može biti vidljiv na brzim pokretima.

  2. Vreme konvergencije. Kada se kamera naglo pomeri ili scena drastično promeni, potrebno je nekoliko frejmova da refleksije "konvergiraju" na tačan rezultat. Tokom tog perioda, refleksije mogu izgledati šumljivo ili neodređeno.

  3. Pokretni objekti. Objekti u pokretu "invalidiraju" akumulirane podatke, što znači da su refleksije pokretnih objekata obično šumljivije od refleksija statičnih.

// Console variables za temporal accumulation:

r.Lumen.Reflections.Temporal 
  // 1 = uključeno (default), 0 = isključeno
  // UPOZORENJE: Isključivanje dramatično smanjuje kvalitet!

r.Lumen.Reflections.TemporalMaxFramesAccumulated
  // Koliko frejmova se akumulira (default: 8-16)
  // Više = čistiji rezultat, ali duže konvergira i više ghosting-a

Denoising

Pored temporal accumulation, Lumen koristi spatial denoiser koji zamućuje šumljive refleksije u prostornom domenu (susedni pikseli) koristeći edge-aware filter koji čuva oštre ivice:

// Denoiser sprečava zamućenje preko ivica:

Pre-denoising:        Post-denoising (edge-aware):
┌──────────────┐     ┌──────────────┐
│ ░░▒▒░░▓▓░░▒▒ │     │ ▒▒▒▒▒▒▓▓▓▓▓▓ │  ← Zamućeno unutar
│ ░░▒▒░░▓▓░░▒▒ │     │ ▒▒▒▒▒▒▓▓▓▓▓▓ │     regiona, ali
│──────────────│     │──────────────│     oštra ivica
│ ▓▓░░▓▓▒▒▓▓░░ │     │ ▓▓▓▓▓▓▒▒▒▒▒▒ │     sačuvana!
│ ▓▓░░▓▓▒▒▓▓░░ │     │ ▓▓▓▓▓▓▒▒▒▒▒▒ │
└──────────────┘     └──────────────┘

26.7.4 Rezolucija refleksija (Reflection Resolution)

Lumen ne trace-uje refleksije na punoj rezoluciji ekrana za svaki piksel. Umesto toga, koristi nižu rezoluciju za trace i zatim upscale-uje rezultat:

// Console variable za kontrolu rezolucije:
r.Lumen.Reflections.DownsampleFactor
  // Default: 1 (puna rezolucija, ako je Quality podešen na visoko)
  // 2 = pola rezolucije (značajno brže, ali manje detalja)

// Napomena: Ovo se automatski podešava na osnovu:
// - Roughness piksela (grublji = niža rezolucija)
// - Quality podešavanja u Post Process Volume-u
// - Scalability settings-a

Kako rezolucija utiče na kvalitet

Rezolucija Performanse Kvalitet Kada koristiti
Puna (1x) Najsporije Najbolji Archviz, cinematics
Pola (0.5x) Dobar balans Dobar za rough površine Igre na visokim podešavanjima
Četvrtina (0.25x) Najbrže Vidljive neoštrosti Igre na niskim podešavanjima

26.7.5 Scalability Settings

Unreal Engine koristi Scalability sistem za automatsko podešavanje kvaliteta na osnovu hardvera. Za refleksije, relevantna je Reflection Quality kategorija:

// Engine/Config/BaseScalability.ini ili vaš projekat

[ReflectionQuality@0]  // Low
r.Lumen.Reflections.Quality=0.25
r.Lumen.Reflections.ScreenTraces=1

[ReflectionQuality@1]  // Medium
r.Lumen.Reflections.Quality=0.5
r.Lumen.Reflections.ScreenTraces=1

[ReflectionQuality@2]  // High
r.Lumen.Reflections.Quality=1.0
r.Lumen.Reflections.ScreenTraces=1

[ReflectionQuality@3]  // Epic
r.Lumen.Reflections.Quality=1.0
r.Lumen.Reflections.ScreenTraces=1
r.Lumen.Reflections.HardwareRayTracing=1  // Ako je podržano

[ReflectionQuality@4]  // Cinematic
r.Lumen.Reflections.Quality=2.0
r.Lumen.Reflections.HardwareRayTracing=1

26.7.6 Kada smanjiti ili isključiti refleksije

Postoje situacije gde smanjenje kvaliteta refleksija ili njihovo potpuno isključivanje ima smisla:

Scenario 1: GPU-bound igra

Ako Stat GPU pokazuje da su refleksije dominantan trošak i imate GPU-bound frame rate problem:

  1. Smanjite Lumen Reflection Quality na 0.5 u Post Process Volume-u.
  2. Smanjite r.Lumen.Reflections.MaxRoughness na 0.4 (manje piksela zahteva trace).
  3. Isključite HW RT refleksije ako su uključene.
  4. Kao poslednje sredstvo, prebacite se na Reflection Captures (ali gubite dinamičnost).

Scenario 2: Zatvoreni prostor bez reflektivnih površina

Ako vaša scena nema značajne reflektivne površine (sve je roughness 0.6+), refleksije su uglavnom pokrivene GI sistemom. Možete smanjiti reflection quality bez vidljive razlike.

Scenario 3: Distant views

Za scene koje prikazuju udaljene pejzaže (planine, šume, gradske panorame), refleksije su manje važne od GI-ja. Smanjite reflection quality i usmerite budžet na GI kvalitet.

Scenario 4: VR/AR aplikacije

VR zahteva stabilnih 90 FPS (ili 72/120 u zavisnosti od headset-a), što je izuzetno strog budžet. Refleksije su često prvi kandidat za smanjenje:

// Preporučena VR podešavanja za refleksije:
r.Lumen.Reflections.Quality 0.25
r.Lumen.Reflections.ScreenTraces 1       // SSR je jeftin, ostaje uključen
r.Lumen.Reflections.MaxRoughness 0.3     // Samo najglađe površine
r.Lumen.Reflections.HardwareRayTracing 0 // Isključi HW RT

26.7.7 Debug i profiling refleksija

Vizualizacioni modovi

Unreal Engine nudi nekoliko vizualizacionih modova za debugging refleksija:

// U Editor-u: View Mode padajući meni

// 1. Reflection vizualizacija
//    Show > Visualize > Reflections
//    Prikazuje samo reflection doprinos

// 2. Roughness vizualizacija  
//    Buffer Visualization > Roughness
//    Pomoć za identifikaciju površina sa niskim roughness-om

// 3. Lumen specifične vizualizacije
//    View Mode > Lumen > Reflections
//    Prikazuje Lumen-specific reflection podatke

Profiling sa Stat komandama

// Koristite ove komande za merenje performansi refleksija:

Stat GPU
  // Traži red "Reflections" -- vreme u ms

Stat LumenReflections
  // Detaljne statistike Lumen reflection sistema

ProfileGPU
  // Detaljan breakdown svih GPU passova -- traži reflection-related passove

Console komande za isolovan debugging

// Isključi sve refleksije (da vidite razliku):
r.Lumen.Reflections 0

// Isključi samo SSR sloj:
r.Lumen.Reflections.ScreenTraces 0

// Isključi temporal accumulation (da vidite "sirovi" šum):
r.Lumen.Reflections.Temporal 0

// Prikaži samo Surface Cache refleksije (bez SSR):
r.Lumen.Reflections.ScreenTraces 0
r.Lumen.Reflections.HardwareRayTracing 0

26.7.8 Čest problem: "Refleksije su previše šumljive"

Ako primetite šumljive refleksije, evo vodiča za dijagnostiku:

Dijagnoza: Šumljive refleksije

1. Da li je roughness vrlo nizak (< 0.1)?
   ├── DA: Normalno -- oštre refleksije sa 1 ray/pixel su šumljive.
   │        Rešenje: Povećajte temporal accumulation ili ray count.
   └── NE: Nastavite...

2. Da li se kamera ili objekti brzo kreću?
   ├── DA: Temporal accumulation nema dovoljno frejmova za 
   │        konvergenciju. Normalno za brz pokret.
   │        Rešenje: Prihvatite ili smanjite brzinu kamere.
   └── NE: Nastavite...

3. Da li je Temporal Accumulation uključen?
   ├── NE: Uključite! r.Lumen.Reflections.Temporal 1
   └── DA: Nastavite...

4. Da li je Lumen Reflection Quality nizak?
   ├── DA: Povećajte na 1.0 ili više.
   └── NE: Proverite Surface Cache kvalitet 
            (r.Lumen.Visualize.SurfaceCache 1)

26.7.9 Čest problem: "Refleksije se 'plivaju' ili 'drhte'"

"Swimming" ili "jittering" refleksija je čest artefakt, posebno na glatkim površinama:

Uzrok: Temporal jitter pomera pozicije uzoraka između frejmova. Na savršeno glatkim površinama, ovo je vidljivo kao pomeranje refleksije.

Rešenja:

  1. Povećajte roughness sa 0.0 na 0.02-0.05 (neprimetna razlika vizuelno, ali smanjuje swimming).
  2. Povećajte ray count.
  3. Koristite HW RT za te specifične površine.

26.7.10 Čest problem: "Refleksije kasne za stvarnošću"

Refleksije koje prikazuju "staro stanje" scene (npr. vrata su otvorena ali refleksija pokazuje zatvorena):

Uzrok: Surface Cache se ažurira postepeno. Nagla promena u sceni zahteva vreme za propagaciju.

Rešenja:

  1. Ovo je inherentno ograničenje Surface Cache-a -- ne može se potpuno eliminisati.
  2. Za kritične scene, koristite HW RT refleksije (nemaju ovaj problem jer trace-uju pravu geometriju svakog frejma).
  3. Proverite r.Lumen.SurfaceCache.UpdateEveryNFrames -- niža vrednost = češće ažuriranje (ali skuplje).

26.7.11 Čest problem: "Refleksije nedostaju na nekim mesh-evima"

Ako objekat ne pojavljuje u refleksijama:

Moguće uzroci:

  1. Mesh nema Lumen podršku. Proverite da li mesh ima generisane Mesh Cards (Static Mesh Editor > Lumen Settings).
  2. Mesh je Nanite, ali nema fallback. Nanite mesh-evi moraju imati fallback mesh za Surface Cache.
  3. Mesh je previše mali. Veoma mali objekti mogu biti ispod rezolucije Surface Cache-a.
  4. Mesh je translucent. Translucent materijali ne doprinose Surface Cache-u po default-u.
// Proverite u Static Mesh Editor-u:
// Details > Lumen Settings:
//   - Max Lumen Mesh Cards: minimum 12 (default)
//   - Generate Mesh Distance Field: mora biti uključeno

// Za Nanite mesh-eve:
// Nanite Settings > Fallback:
//   - Osigurajte da postoji fallback mesh za Lumen

26.8 Napredne teme

26.8.1 Refleksije na vodi

Vodene površine su poseban izazov za refleksije iz više razloga:

  1. Roughness varira. Mirna voda je skoro savršeno ogledalo (roughness ~0.0), dok uzburkana voda ima značajan roughness.
  2. Normale su dinamične. Vodene normale se menjaju tokom vremena (talasi), što znači da se reflektovani pravac konstantno menja.
  3. Fresnel efekat je jak. Voda je mnogo reflektivnija pod malim uglom (grazing angle) nego direktno odozgo.
  4. Veliku površinu pokriva. Jezero ili okean mogu pokriti značajan deo ekrana, što znači mnogo piksela koji zahtevaju reflection trace.
// Preporuke za vodene refleksije u Lumen-u:

// 1. Koristite Water Plugin za UE5 -- optimizovan je za Lumen.

// 2. Za mirnu vodu (bazen, jezero):
//    - Roughness: 0.0 - 0.05
//    - SSR će pokriti većinu (voda je obično horizontalna 
//      pa reflektuje nebo i okolne objekte koji su na ekranu)
//    - Surface Cache za off-screen sadržaj

// 3. Za okean/more:
//    - Roughness: 0.1 - 0.4 (varira sa talasima)
//    - Niža rezolucija refleksija je prihvatljiva 
//      jer su talasi ionako zamućuju
//    - Razmislite o smanjenom Reflection Quality za performanse

26.8.2 Refleksije u enterijeru vs eksterijeru

Enterijer (zatvoreni prostori)

Eksterijer (otvoreni prostori)

26.8.3 Refleksije i Nanite

Nanite (virtuelna geometrija iz Poglavlja 23) i Lumen refleksije su komplementarni sistemi, ali postoje neke važne interakcije:

  1. Surface Cache i Nanite. Nanite mesh-evi automatski generišu mesh cards za Surface Cache. Međutim, Nanite mesh-evi sa ekstremno visokom gustinom trouglova mogu zahtevati posebnu pažnju za mesh card generisanje.

  2. HW RT i Nanite. Nanite mesh-evi koriste proxy geometriju za ray tracing (jer HW RT ne može direktno trace-ovati Nanite virtualnu geometriju). Ovo znači da HW RT refleksije Nanite mesh-eva mogu imati manje detalja od rasterizovane verzije.

  3. Performance budget. Nanite i Lumen refleksije dele GPU resurse. Scena sa milionima Nanite trouglova i mnogo reflektivnih površina može biti previše zahtevna čak i za high-end hardware.

26.8.4 Multi-bounce refleksije

U realnom svetu, svetlost se odbija više puta: ogledalo reflektuje drugo ogledalo, što reflektuje treće ogledalo, itd. U Lumen-u:

// Za HW RT multi-bounce refleksije:
r.RayTracing.Reflections.MaxBounces 2
  // 1 = samo direktna refleksija (default)
  // 2 = refleksija refleksije (ogledalo u ogledalu)
  // 3+ = veoma skupo, koristite samo za specifične potrebe

Za Software tracing (Surface Cache), multi-bounce refleksije su indirektno podržane -- Surface Cache uključuje informacije o indirektnom osvetljenju, pa refleksija prirodno "sadrži" GI informacije, ali ne čiste refleksije refleksija.

26.8.5 Refleksije i Post Processing

Lumen refleksije se računaju pre većine post-processing efekata. Ovo znači:

Ovo je generalno korektno ponašanje, ali ponekad refleksije mogu izazvati neželjene efekte sa bloom-om (presvetli odsjaji u refleksijama koji generišu preveliki bloom).


26.9 Praktičan vodič: Podešavanje Lumen refleksija za vaš projekat

26.9.1 Korak po korak: Osnovno podešavanje

// 1. Uključite Lumen u Project Settings:
//    Project Settings > Engine > Rendering > Global Illumination
//    Dynamic Global Illumination Method: Lumen
//    Reflection Method: Lumen

// 2. Proverite da imate SkyLight u sceni:
//    SkyLight pruža fallback za refleksije neba

// 3. Proverite da mesh-evi imaju Lumen podršku:
//    Static Mesh Editor > Details > Lumen Settings
//    Generate Mesh Distance Field: true

// 4. Postavite Post Process Volume:
//    - Infinite Extent (unbound) = true
//    - Lumen Reflections Quality: 1.0
//    - (opciono) Lumen Reflection Method: površinski podrazumevana

26.9.2 Korak po korak: Optimizacija za igre

// Za igre koje ciljaju 60 FPS:

// 1. Koristite Scalability High ili Medium
sg.ReflectionQuality 2

// 2. Ograničite max roughness za refleksije
r.Lumen.Reflections.MaxRoughness 0.4

// 3. SSR ostaje uključen (jeftin i efikasan)
r.Lumen.Reflections.ScreenTraces 1

// 4. Isključite HW RT refleksije (osim ako ciljate high-end)
r.Lumen.Reflections.HardwareRayTracing 0

// 5. Postavite Reflection Capture Actors kao fallback
//    - 1 po sobi je dovoljno
//    - SkyLight za otvorene prostore

// 6. Proverite sa Stat GPU da refleksije ne prelaze 2ms

26.9.3 Korak po korak: Maksimalni kvalitet za Archviz

// Za archviz koji cilja fotorealizam:

// 1. Uključite HW RT za refleksije
r.Lumen.Reflections.HardwareRayTracing 1

// 2. Povećajte kvalitet
r.Lumen.Reflections.Quality 2.0

// 3. Dozvolite multi-bounce (ogledala u ogledalu)
r.RayTracing.Reflections.MaxBounces 2

// 4. Povećajte temporal accumulation
r.Lumen.Reflections.TemporalMaxFramesAccumulated 32

// 5. Koristite punu rezoluciju za trace
r.Lumen.Reflections.DownsampleFactor 1

// 6. Budžet za refleksije: do 5-8ms je prihvatljivo za 30 FPS

26.9.4 Korak po korak: Debugging problema

// Ako refleksije ne rade kako očekujete:

// 1. Proverite da je Lumen uključen
//    Project Settings > Rendering > Reflection Method: Lumen

// 2. Izolujte problem
r.Lumen.Reflections.ScreenTraces 0  // Isključi SSR
// Ako refleksije nestanu na ekranu ali rade off-screen = SSR je bio jedini izvor

r.Lumen.Reflections 0  // Isključi sve Lumen refleksije
// Ako se vrate Reflection Capture refleksije = Lumen je radio ali možda loše

// 3. Proverite Surface Cache
r.Lumen.Visualize.SurfaceCache 1
// Potražite praznine ili artefakte na mesh-evima koji nemaju refleksiju

// 4. Proverite materijal
// Da li je roughness previsok? Buffer Visualization > Roughness

// 5. Proverite mesh
// Static Mesh Editor > Lumen Settings > Max Lumen Mesh Cards
// Povećajte ako je mesh slabo pokriven

26.10 Referenciranje prethodnih poglavlja

Kroz ovo poglavlje, višestruko smo se pozivali na koncepte iz ranijih poglavlja. Evo jasnog pregleda tih veza:

Poglavlje 11: PBR Materijali i Roughness

U Poglavlju 11 smo detaljno obradili kako PBR materijali funkcionišu, uključujući roughness parametar. Roughness je fundamentalan za razumevanje cene i kvaliteta refleksija -- kao što smo videli u sekciji 26.6, roughness direktno kontroliše koliko je refleksija oštra ili zamućena, koliko zraka je potrebno, i na kojoj rezoluciji se trace izvršava. Ako niste sigurni kako roughness utiče na izgled materijala, preporučujemo da se vratite na Poglavlje 11.

Poglavlje 15: Post-Processing i Screen-Space efekti

U Poglavlju 15 smo obradili SSR kao post-processing efekat. U Lumen kontekstu, SSR nije samostalan sistem već prvi sloj u višeslojnom reflection pipeline-u (sekcija 26.2). Razumevanje SSR mehanizma (ray marching kroz depth buffer, ograničenja screen space-a) iz Poglavlja 15 je ključno za razumevanje zašto Lumen koristi SSR kao prvi, najjeftiniji pokušaj.

Poglavlje 25: Lumen Global Illumination

Poglavlje 25 je direktan prethodnik ovog poglavlja. Surface Cache koji smo detaljno obradili u kontekstu GI-ja je isti Surface Cache koji Lumen refleksije koriste kao fallback (sekcija 26.3). Razumevanje kako se Surface Cache gradi, ažurira, i koji su mu limiti je esencijalno za razumevanje kvaliteta i ograničenja Lumen refleksija.


26.11 Rezime poglavlja

Hajde da sumiramo šta smo naučili:

  1. Refleksije su fundamentalno teške u real-time renderingu jer zahtevaju znanje o sceni iz perspektive koja nije kamerina.

  2. Tradicionalni pristupi (Reflection Captures, Planar Reflections, standalone SSR) imaju značajna ograničenja -- statičnost, parallax error, nemogućnost prikaza off-screen sadržaja.

  3. Lumen koristi višeslojni pristup:

    • SSR kao prvi, najjeftiniji sloj -- radi za ono što je vidljivo na ekranu.
    • Surface Cache trace kao fallback -- pokriva off-screen sadržaj, niža rezolucija.
    • Hardware RT kao opcioni premium sloj -- najviši kvalitet, najskuplji.
    • Reflection Captures kao poslednji fallback -- statični, ali pouzdani.
  4. Roughness fundamentalno utiče na cenu refleksija:

    • Glatke površine (roughness 0-0.1): Oštre, jeftine po zraku ali zahtevne za kvalitet.
    • Srednje površine (roughness 0.1-0.5): Najskuplje -- zahtevaju mnogo uzoraka.
    • Grube površine (roughness 0.5-0.8): Pokrivene kombinacijom refleksija i GI.
    • Veoma grube (roughness 0.8+): GI potpuno preuzima.
  5. Optimizacija refleksija uključuje balansiranje ray count-a, rezolucije, temporal accumulation, i strateški izbor roughness vrednosti u materijalima.

  6. HW RT refleksije imaju smisla za archviz, cinematics, i hero momente, ali su preskupe za većinu gameplay scenarija na trenutnom hardveru.


26.12 Tabela ključnih pojmova

Termin Opis
Screen-Space Reflections (SSR) Tehnika refleksija bazirana na ray marching-u kroz depth buffer; može reflektovati samo sadržaj vidljiv na ekranu.
Surface Cache Lumen-ova cache-irana reprezentacija scene koristeći Mesh Cards; koristi se za tracing kada SSR zakaže.
Hardware Ray Tracing (HW RT) Ray tracing koji koristi dedicirane RT cores na GPU-u za trace protiv pravih trouglova.
Reflection Capture Actor Legacy aktor koji snima statički cubemap scene za refleksije; služi kao poslednji fallback u Lumen-u.
Cubemap Tekstura sastavljena od 6 slika koje pokrivaju svih 360 stepeni okruženja.
Ray Marching Tehnika iterativnog koračanja kroz prostor (ili buffer) u potrazi za presekom.
Depth Buffer Buffer koji za svaki piksel čuva udaljenost od kamere do najbliže površine.
Roughness PBR parametar koji definiše koliko je mikro-površina materijala gruba (0 = ogledalo, 1 = potpuno difuzno).
Temporal Accumulation Tehnika akumuliranja rezultata iz više frejmova za smanjenje šuma.
Denoising Proces uklanjanja šuma iz rezultata ray tracing-a, prostorno (spatial) ili vremenski (temporal).
Ghosting Artefakt temporal accumulation gde "duh" starog stanja scene ostaje vidljiv nakon promene.
BVH (Bounding Volume Hierarchy) Hijerarhijska struktura podataka koja ubrzava pronalaženje preseka zraka sa geometrijom.
BLAS / TLAS Bottom/Top Level Acceleration Structure -- dvostruka hijerarhija za HW RT (per-mesh i per-scene).
Mesh Cards Ravne kartice koje aproksimiraju površine mesh-a za Surface Cache sistem.
Parallax Error Greška u refleksijama uzrokovana razlikom između pozicije gde je cubemap snimljen i gde se koristi.
Planar Reflection Tehnika renderovanja scene iz reflektovane kamere za ravne reflektivne površine.
Fresnel Effect Fizički fenomen gde površina postaje reflektivnija pod plićim uglom gledanja.
Specular Komponenta osvetljenja koja odgovara direktnim refleksijama svetlosti (suprotno od diffuse).
GI (Global Illumination) Simulacija indirektnog osvetljenja -- svetlost koja se odbija od površina i osvetljava okolinu.
Scalability UE5 sistem za automatsko podešavanje kvaliteta renderinga na osnovu hardverskih mogućnosti.
Motion Rejection Tehnika u temporal accumulation koja odbacuje stare podatke za piksele koji su se pomerili.

26.13 Dodatni resursi i reference

Zvanična dokumentacija

Epic Games prezentacije

Članci i blogovi

Povezana poglavlja u ovoj knjizi

Poglavlje Tema Relevantnost za refleksije
Poglavlje 11 PBR materijali Roughness, Metallic, Specular -- kako materijali definišu reflektivno ponašanje
Poglavlje 15 Post-Processing SSR kao post-processing efekat, depth buffer, screen-space tehnike
Poglavlje 23 Nanite Virtuelna geometrija i njena interakcija sa Lumen Surface Cache i HW RT
Poglavlje 25 Lumen GI Surface Cache, Mesh Cards, SDF -- fundamenti na kojima Lumen refleksije rade

U sledećem poglavlju (Poglavlje 27), prelazimo na praktičnu primenu svega što smo naučili o Lumen-u -- kreiramo kompletnu scenu od nule sa optimizovanim GI i refleksijama, profilišemo performanse, i rešavamo česte probleme koje ćete sresti u produkciji.


Kraj Poglavlja 26