Poglavlje 22: UE5 Material System — Specifično
"Materijali su koža vašeg sveta. Bez njih, svaka geometrija je samo siva masa poligona."
Uvod
Dobrodošli u jedno od najvažnijih poglavlja ove knjige. Ako ste pratili poglavlja 17 (shader programiranje), 18 (modeli materijala) i 21 (optimizacija shadera), sada imate solidne temelje za razumevanje GPU pipeline-a. U ovom poglavlju spuštamo se na nivo Unreal Engine 5 Material System-a — konkretnog alata koji vam omogućava da sve te teorijske koncepte primenite u praksi.
UE5 Material System je, bez preterivanja, jedan od najsofisticiranijih sistema za kreiranje materijala u bilo kojem game engine-u. On vam pruža vizuelni, node-based interfejs koji generiše optimizovani HLSL shader kod, a da vi pri tom ne morate da pišete nijednu liniju koda ručno. Naravno, možete pisati custom HLSL — i ponekad ćete morati — ali za ogromnu većinu slučajeva, graf je sve što vam treba.
U ovom poglavlju detaljno ćemo pokriti:
- Kako Material Graph funkcioniše i šta se dešava "ispod haube"
- Zašto su Material Instances apsolutno kritični za performanse
- Kako Material Parameter Collections omogućavaju globalne parametre
- Material Layers sistem za kompleksne površine
- Substrate — novi model materijala u UE5.x
- Shader kompilacija i PSO caching
- Optimizacija materijala od A do Ž
Hajde da počnemo.
22.1 Material Graph — Vizuelno Kreiranje Shadera
22.1.1 Šta je Material Graph?
Material Graph je vizuelni editor u kojem kreirate materijale koristeći čvorove (nodes) i veze (connections) između njih. Svaki čvor predstavlja jednu operaciju — može biti jednostavna (množenje dve vrednosti) ili kompleksna (celokupan noise pattern). Kada povežete čvorove žicama, vi zapravo gradite shader program bez pisanja koda.
Ovo zvuči jednostavno, ali je zapravo izuzetno moćan koncept. Pogledajmo šta se dešava kada vi, recimo, spojite Texture Sample čvor sa Base Color ulazom vašeg materijala:
[Texture Sample] -----> [Main Material Node: Base Color]
Iza kulisa, engine uzima ovaj graf i kompajlira ga u HLSL (High-Level Shading Language) kod koji GPU može da izvrši. Taj HLSL kod se zatim kompajlira u platform-specifični shader bytecode — DirectX shader za Windows, Metal shader za macOS/iOS, Vulkan SPIR-V za Android i Linux, itd.
22.1.2 Kako Nodes Kompajliraju u HLSL Kod
Svaki node u Material Graph-u ima svoju internu HLSL implementaciju. Kada UE5 Material Compiler prolazi kroz graf, on:
- Traversira graf od Main Material Node-a unazad (od izlaza ka ulazima)
- Prikuplja sve čvorove koji su povezani i doprinose konačnom izlazu
- Generiše HLSL funkcije za svaki čvor
- Optimizuje kod eliminacijom neiskorišćenih grana i konstantnih izraza
- Spaja sve u jedan koherentan shader program
Na primer, sledeći jednostavni graf:
[Constant3Vector (1, 0, 0)] ----> [Multiply] ----> [Base Color]
[Scalar Parameter "Intensity"] ---/
Generiše otprilike ovakav HLSL kod (pojednostavljeno):
// Auto-generated by UE5 Material Compiler
float3 Local0 = float3(1.0, 0.0, 0.0); // Constant3Vector
float Local1 = MaterialParameterScalar_Intensity; // Scalar Parameter
float3 Local2 = Local0 * Local1; // Multiply
// Assign to material output
PixelMaterialInputs.BaseColor = Local2;
Naravno, stvarni generisani kod je znatno kompleksniji — sadrži razne macro-e, uniform buffer reference, platform-specifične adaptacije i optimizacije — ali suština je ista. Svaki čvor postaje jedna ili više linija HLSL koda.
Savet: Možete videti generisani HLSL kod za bilo koji materijal klikom na Window → Shader Code → HLSL Code unutar Material Editor-a. Ovo je izuzetno korisno za debugging i razumevanje šta vaš graf zapravo radi.
22.1.3 Graf kao Apstrakcija nad Raw Shader Kodom
Zašto koristiti graf umesto da pišemo HLSL direktno? Nekoliko razloga:
Pristupačnost. Umetnici i tehnički dizajneri mogu kreirati kompleksne materijale bez poznavanja programiranja. Graf je vizuelan, intuitivan, i pruža instant preview rezultata.
Cross-platform kompatibilnost. Kada pišete HLSL ručno, vi pišete za jednu platformu. Material Graph automatski generiše kod za sve ciljne platforme — DirectX 11, DirectX 12, Vulkan, Metal, OpenGL ES. Jedna definicija, više izlaza.
Automatska optimizacija. UE5 Material Compiler primenjuje niz optimizacija koje bi bile teške za ručnu implementaciju: constant folding, dead code elimination, instruction scheduling, i još mnogo toga. Videćemo ovo detaljnije u sekciji 22.7.
Integracija sa engine-om. Material Graf se automatski integriše sa svim engine sistemima — lighting, shadows, translucency, Lumen, Nanite, Virtual Shadow Maps. Ručno pisani shader bi morao da implementira sve ove integracije ručno.
Safety net. Grafički sistem sprečava mnoge klase grešaka koje su česte u ručno pisanom kodu — type mismatch, nevalidne operacije, missing inputs. Compiler vas upozorava na probleme pre nego što materijal stigne na GPU.
Naravno, graf ima i ograničenja. Kompleksni flow control (petlje, složena grananja), pristup custom data strukturama, ili veoma specifične optimizacije ponekad zahtevaju Custom Expression čvorove ili čak custom shader code (o čemu smo govorili u Poglavlju 17). Ali za 90%+ slučajeva, graf je superioran pristup.
22.1.4 Main Material Node i Njegovi Ulazi
Srce svakog materijala je Main Material Node — veliki čvor na desnoj strani grafa u koji vodite sve svoje kalkulacije. Ovaj čvor definiše izlaze vašeg materijala, odnosno podatke koje shader šalje rendering pipeline-u.
Pogledajmo sve ulaze:
Base Color
- Tip:
float3(RGB) - Opseg: 0.0 — 1.0 (linearni prostor boja)
- Značenje: Osnovna boja površine, tj. albedo. Ovo je boja koju površina ima bez ikakvog osvetljenja.
- Napomena: Za fizički korektne materijale, izbegavajte čisto crnu (0, 0, 0) i čisto belu (1, 1, 1). Realni materijali imaju albedo u opsegu ~0.02—0.95.
Metallic
- Tip:
float(scalar) - Opseg: 0.0 (dielektrik) — 1.0 (metal)
- Značenje: Da li je površina metal ili ne-metal. U praksi, ovo je skoro uvek 0 ili 1 — prelazne vrednosti se koriste samo za mešovite površine (npr. zarđali metal).
Specular
- Tip:
float(scalar) - Opseg: 0.0 — 1.0 (default: 0.5)
- Značenje: Kontroliše jačinu Fresnel refleksije za ne-metalne površine. Vrednost 0.5 odgovara indeksu refrakcije ~1.5, što je tipično za većinu dielektričnih materijala (plastika, staklo, drvo).
Roughness
- Tip:
float(scalar) - Opseg: 0.0 (savršeno gladak, ogledalski) — 1.0 (potpuno hrapav, difuzni)
- Značenje: Mikro-hrapavost površine. Kontroliše koliko je specular highlight širok i koliko su refleksije oštre.
Emissive Color
- Tip:
float3(RGB) - Opseg: 0.0 — neograničeno (HDR)
- Značenje: Svetlost koju površina emituje. Vrednosti iznad 1.0 su dozvoljene i proizvode bloom efekat sa Lumen ili post-process bloom-om.
Normal
- Tip:
float3(tangent-space normal) - Značenje: Perturbacija surface normal-a za iluziju detaljne geometrije bez stvarnih poligona. Obično dolazi iz normal map teksture.
World Position Offset
- Tip:
float3 - Značenje: Pomera vertex pozicije u world space-u. Koristi se za vegetaciju koja se njiha na vetru, ocean wave simulaciju, i slično. Ovo je vertex shader operacija.
Ambient Occlusion
- Tip:
float(scalar) - Opseg: 0.0 (potpuno zaklonjen) — 1.0 (potpuno izložen)
- Značenje: Lokalna ambijentalna okluzija koja se primenjuje pre globalnog AO-a.
Opacity / Opacity Mask
- Tip:
float(scalar) - Značenje: Prozirnost materijala. Opacity se koristi za translucent materijale (kontinualna prozirnost), dok Opacity Mask koristi threshold (obično 0.5) za binarne odluke (vidljivo ili nevidljivo, npr. lišće drveća).
Pixel Depth Offset
- Tip:
float(scalar) - Značenje: Virtuelno pomera pixel dubinu — korisno za parallax occlusion mapping ili blending sa terenom.
Refraction
- Tip:
float(index prelamanja) ilifloat2(offset) - Značenje: Za providne materijale — koliko se svetlost prelama prolazeći kroz površinu.
Subsurface Color
- Tip:
float3(RGB) - Značenje: Boja svetlosti koja se prenosi kroz materijal. Koristi se sa Subsurface shading model-om za kožu, vosak, lišće, itd.
Tangent
- Tip:
float3 - Značenje: Custom tangent vektor za anizotropno osvetljenje (četkani metal, kosa).
Ne morate (i ne treba) povezati sve ulaze. Nepovezani ulazi koriste default vrednosti. Samo povežite ono što vam je zaista potrebno — svaki povezani ulaz dodaje instrukcije u shader, a time i cenu renderovanja.
22.1.5 Material Domain i Blend Mode
Pored ulaza, Main Material Node ima svojstva (properties) koja fundamentalno menjaju kako se materijal ponaša:
Material Domain:
- Surface — Standard 3D površina (najčešće)
- Deferred Decal — Projekcija na druge površine
- Light Function — Modifikacija svetlosnog oblika
- Volume — Volumetrijski efekat (magla, oblaci)
- Post Process — Full-screen efekat
- User Interface — UMG/Slate UI materijal
Blend Mode:
- Opaque — Potpuno neprovidan. Najjeftiniji za renderovanje. Podržava sve lighting feature-e.
- Masked — Opaque sa rupama (definisanim kroz Opacity Mask). Koristi alpha test.
- Translucent — Delimično providan. Skuplji, ograničeni lighting.
- Additive — Dodaje boju na pozadinu (sjaj, plamen, hologrami).
- Modulate — Množi boju pozadine (senke, zamračenje).
- Alpha Composite — Pre-multiplied alpha blending.
Shading Model (o čemu smo detaljno govorili u Poglavlju 18):
- Default Lit
- Unlit
- Subsurface
- Subsurface Profile
- Clear Coat
- Two Sided Foliage
- Hair
- Cloth
- Eye
- Single Layer Water
- Thin Translucent
- From Material Expression (runtime odabir — skupo!)
Svaka kombinacija Domain + Blend Mode + Shading Model generiše drugačiji shader. Ovo je važno zapamtiti jer direktno utiče na shader permutation count, o čemu ćemo govoriti u sekciji o kompilaciji.
22.2 Material Instances — Zašto su Kritični
22.2.1 Problem: Svaki Materijal = Novi Shader
Zamislite sledeći scenario: pravite RPG igru. Imate 50 različitih tipova oklopa. Svaki oklop koristi isti shader logic — Base Color tekstura, Normal mapa, Metallic/Roughness mapa, i nekoliko parametara za prilagođavanje boja. Jedina razlika između oklopa je koje teksture i koje vrednosti parametara koriste.
Naivni pristup bi bio: napravite 50 zasebnih materijala, svaki sa identičnim grafom ali različitim teksturama. Rezultat?
50 materijala × N platformskih varijanti × M quality levels = STOTINE kompajliranih shadera
Svaki od tih shadera mora da se:
- Kompajlira — što traje (ponekad minuti po shaderu)
- Čuva u memoriji — GPU memorija za shader bytecode
- Prebacuje na GPU pri renderovanju — shader state change je jedna od najskupljih operacija
Ovo je klasičan problem shader permutation explosion i jedan je od glavnih ubica performansi u real-time renderovanju. Srećom, UE5 ima elegantan odgovor.
22.2.2 Rešenje: Material Instances
Material Instance je koncept koji razdvaja logiku shadera od podataka shadera. Evo kako funkcioniše:
- Kreirate jedan Parent Material (master material) sa svim čvorovima, logikom, i definisanim parametrima
- Kreirate Material Instance koji referencira taj parent material
- U instance-u menjate samo vrednosti parametara — teksture, boje, skalarne vrednosti
- Instance koristi isti kompajlirani shader kao parent material
Parent Material (M_Armor)
├── Material Instance (MI_Armor_Iron) ← isti shader, drugačije teksture
├── Material Instance (MI_Armor_Gold) ← isti shader, drugačije teksture
├── Material Instance (MI_Armor_Silver) ← isti shader, drugačije teksture
└── Material Instance (MI_Armor_Bronze) ← isti shader, drugačije teksture
Umesto 50 shadera, sada imate jedan shader i 50 setova parametara. Kompilacija je brža, memorija je štedljivija, a runtime performanse dramatično bolje jer GPU ne mora da menja shader program — samo uniform buffer sa parametrima.
22.2.3 Kreiranje Parametara u Parent Materijalu
Da bi Material Instance mogao da menja neku vrednost, ta vrednost mora biti definisana kao Parameter u parent materijalu. Postoji više tipova parametara:
Scalar Parameter:
Desni klik → Material Expression → Scalar Parameter
- Definiše jednu float vrednost
- Primer: Roughness Intensity, Emissive Strength, Tiling Scale
- Ima Default Value, Min/Max opseg, i Group za organizaciju
Vector Parameter:
Desni klik → Material Expression → Vector Parameter
- Definiše float4 (RGBA) vrednost
- Primer: Base Tint Color, Emissive Color
- U instance-u se prikazuje kao color picker
Texture Parameter:
Desni klik → Material Expression → Texture Sample → Convert to Parameter
- Omogućava zamenu teksture u instance-u
- Primer: Albedo Map, Normal Map, ORM Map
Static Switch Parameter:
Desni klik → Material Expression → Static Switch Parameter
- Boolean koji bira između dve grane grafa
- VAŽNO: Ovo je statički switch — menja se u editor-u, ne runtime
- Svaka kombinacija static switch-eva generiše novu shader permutaciju
- Koristite ih umešno! (Više o ovome u sekciji 22.7)
Static Component Mask Parameter:
- Omogućava biranje kanala (R, G, B, A) iz teksture
- Statički — svaka konfiguracija = nova permutacija
Font Parameter:
- Za UI materijale — omogućava promenu fonta u instance-u
22.2.4 Hijerarhija Material Instance-a
Material Instance-i mogu imati hijerarhijsku strukturu — instance može biti "dete" drugog instance-a:
M_Character (Parent Material)
├── MI_Character_Human (Instance - overrides skin tint)
│ ├── MI_Character_Human_Male (Instance - overrides body textures)
│ └── MI_Character_Human_Female (Instance - overrides body textures)
├── MI_Character_Orc (Instance - overrides skin tint to green)
│ ├── MI_Character_Orc_Warrior (Instance - adds scars)
│ └── MI_Character_Orc_Shaman (Instance - adds tattoos)
└── MI_Character_Elf (Instance - overrides ear normal map)
Svaki nivo u hijerarhiji može override-ovati parametre svog roditelja. Parametri koji nisu override-ovani nasleđuju vrednost od roditelja. Ovo je klasičan inheritance pattern i omogućava veoma organizovanu strukturu materijala.
Pravilo: Svi instance-i u hijerarhiji, bez obzira na dubinu, koriste shader od root parent materijala. Hijerarhija utiče samo na default vrednosti parametara.
22.2.5 Material Instance Constant (MIC) vs Dynamic Material Instance (DMI)
UE5 razlikuje dve vrste Material Instance-a sa veoma različitim ponašanjima:
Material Instance Constant (MIC)
// Kreiran u Content Browser-u
// UClass: UMaterialInstanceConstant
- Kreiran u editoru (Content Browser → desni klik → Material Instance)
- Parametri se postavljaju pre pokretanja igre
- Nema runtime overhead za promenu parametara (jer se ne menjaju runtime)
- Deo asset sistema — čuva se na disku, može se referencirati u Blueprint-ovima
- Ovo je ono što koristite u 90% slučajeva
Dynamic Material Instance (DMI)
// Kreiran u kodu:
UMaterialInstanceDynamic* DynMat =
UMaterialInstanceDynamic::Create(ParentMaterial, this);
// Ili u Blueprint-u:
// Create Dynamic Material Instance node
// Promena parametara runtime:
DynMat->SetScalarParameterValue("Opacity", 0.5f);
DynMat->SetVectorParameterValue("Color", FLinearColor::Red);
DynMat->SetTextureParameterValue("MainTexture", MyTexture);
- Kreiran u kodu ili Blueprint-u tokom runtime-a
- Parametri se mogu menjati svaki frame ako je potrebno
- Ima runtime cost — svaki DMI je zasebna instanca koja mora da se prati
- Ne čuva se na disku — kreira se dinamički
- Koristi se za: health bar koji menja boju, materijal koji bledi, dissolve efekat, hit flash, itd.
Česta greška: Kreiranje novog DMI svakog frame-a. Ovo je memorijski leak! Kreirajte DMI jednom (npr. u BeginPlay) i zatim samo menjajte parametre.
// POGREŠNO - memory leak!
void AMyActor::Tick(float DeltaTime)
{
UMaterialInstanceDynamic* Mat =
UMaterialInstanceDynamic::Create(ParentMat, this);
Mat->SetScalarParameterValue("Health", CurrentHealth);
MeshComp->SetMaterial(0, Mat); // Prethodni DMI ostaje u memoriji!
}
// ISPRAVNO
void AMyActor::BeginPlay()
{
DynMat = UMaterialInstanceDynamic::Create(ParentMat, this);
MeshComp->SetMaterial(0, DynMat);
}
void AMyActor::Tick(float DeltaTime)
{
DynMat->SetScalarParameterValue("Health", CurrentHealth);
}
22.2.6 Performansne Implikacije
Hajde da kvantifikujemo zašto su Material Instance-i toliko važni:
| Scenario | Shadera | Shader Memorija | State Changes |
|---|---|---|---|
| 50 zasebnih materijala | 50+ | ~50× veća | Čest |
| 1 parent + 50 instances | 1 | 1× | Retko |
| Ušteda | ~98% | ~98% | Dramatična |
Shader state change (prebacivanje sa jednog shadera na drugi) je jedna od najskupljih operacija na GPU-u. Kada koristite Material Instance-e, GPU koristi isti shader program i samo menja uniform buffer sa parametrima — operacija koja je reda veličine jeftinija.
UE5 automatski sortira draw call-ove po materijalu da minimizuje state change-ove. Kada svi vaši objekti koriste instance istog parent materijala, oni se automatski grupišu zajedno, što dalje poboljšava performanse.
22.3 Material Parameter Collections (MPC)
22.3.1 Šta su Material Parameter Collections?
Material Parameter Collection (MPC) je globalni set parametara koji može biti referenciran od strane bilo kog materijala u projektu. Zamislite ga kao "global variables" za vaš material sistem.
Za razliku od Material Instance parametara koji su specifični za jednu instancu materijala, MPC parametri su deljeni — promenite ih jednom, i svaki materijal koji ih koristi automatski vidi novu vrednost.
22.3.2 Kreiranje i Korišćenje MPC-a
Kreiranje:
- Content Browser → desni klik → Materials & Textures → Material Parameter Collection
- Otvorite kreirani asset
- Dodajte Scalar Parameters i/ili Vector Parameters
Korišćenje u materijalu:
- U Material Graph-u, desni klik → Collection Parameter
- Izaberite vaš MPC asset i željeni parametar
- Koristite output kao bilo koji drugi čvor
Ažuriranje iz koda:
// C++
UMaterialParameterCollection* MPC = LoadObject<UMaterialParameterCollection>(
nullptr, TEXT("/Game/Materials/MPC_GlobalParams"));
UKismetMaterialLibrary::SetScalarParameterValue(
GetWorld(), MPC, "WindStrength", 2.5f);
UKismetMaterialLibrary::SetVectorParameterValue(
GetWorld(), MPC, "SunColor", FLinearColor(1.0f, 0.9f, 0.7f, 1.0f));
// Blueprint:
// Set Scalar Parameter Value (Collection)
// Set Vector Parameter Value (Collection)
22.3.3 Tipični Use Case-ovi
1. Vetar (Wind):
MPC_Environment:
- WindDirection: Vector (XYZ smer vetra)
- WindStrength: Scalar (jačina vetra)
- WindSpeed: Scalar (brzina oscilacije)
Svi materijali za vegetaciju (trava, drveće, zastave) referenciraju ove parametre za World Position Offset animaciju. Promenite WindStrength jednom — sva vegetacija reaguje.
2. Doba dana (Time of Day):
MPC_TimeOfDay:
- SunDirection: Vector
- SunColor: Vector
- SkyIntensity: Scalar
- FogDensity: Scalar
Materijali koji koriste custom sky rendering, fog kalkulacije, ili ambient efekte čitaju iz ovog MPC-a.
3. Globalni tint / Color grading:
MPC_Gameplay:
- DamageOverlayIntensity: Scalar (crveni overlay kad je igrač povređen)
- PoisonTint: Vector (zelenkasti tint za otrov)
- NightVisionIntensity: Scalar (noćni vid)
4. Interaktivni svet:
MPC_PlayerInteraction:
- PlayerPosition: Vector (pozicija igrača za proximity efekte)
- InteractionRadius: Scalar
Materijali terena, trave, vode mogu koristiti PlayerPosition da reaguju na blizinu igrača — trava se savija, voda se talasa, sneg se topi.
22.3.4 Ograničenja MPC-a
MPC ima neka ograničenja o kojima morate znati:
- Maksimalno 1024 skalarna parametra i 1024 vektorska parametra po kolekciji (što je u praksi više nego dovoljno)
- Nema teksturnih parametara — MPC podržava samo scalars i vectors
- MPC ažuriranje se dešava na CPU-u i šalje se na GPU kroz uniform buffer — veoma brzo, ali ipak postoji latencija od jednog frame-a
- Ne možete imati previše različitih MPC-ova referenciranih u jednom materijalu — svaki MPC zauzima jedan uniform buffer slot
22.3.5 Performanse MPC-a
MPC je izuzetno jeftin za korišćenje. Evo zašto:
- Jedan uniform buffer update po frame-u za ceo MPC — bez obzira koliko materijala ga koristi
- Nema shader recompilation pri promeni vrednosti — to su runtime uniform-i
- GPU čitanje iz uniform buffer-a je konstantno vreme (O(1))
- Mnogo efikasnije od alternativa (npr. ažuriranje parametara na svakom DMI-u pojedinačno)
Praktično pravilo: ako imate parametar koji treba da utiče na mnogo materijala istovremeno, koristite MPC umesto da ažurirate stotine DMI-ova.
22.4 Material Layers
22.4.1 Problem Kompleksnih Površina
U realnom svetu, površine retko imaju jednoličan izgled. Zid može biti delimično ofarban, delimično ogoljeno drvo, sa mrljama vlage i mahovinom u uglovima. Teren može imati travu, blato, stene, i sneg — sve sa glatkim prelazima.
Tradicionalni pristup ovom problemu u Material Graph-u izgleda ovako:
[Teksture za materijal A] → [Lerp] → [Lerp] → [Lerp] → [Base Color]
[Teksture za materijal B] →---/ | |
[Teksture za materijal C] →-----------/ |
[Teksture za materijal D] →-------------------/
[Blend maske] →---/---/---/
Sa svakim novim slojem, graf postaje eksponencijalno složeniji. Za 4 sloja terena, imate minimum 12 teksturnih uzorkovanja (3 teksture × 4 sloja — albedo, normal, ORM za svaki sloj), plus maske, plus blend logiku. Graf postaje nečitljiv i teško ga je održavati.
22.4.2 Material Layers Sistem
UE5 Material Layers sistem rešava ovaj problem kroz modularnost. Umesto da sve radite u jednom ogromnom grafu, razdvajate materijal na:
- Material Layer — definicija jednog "materijala" (npr. trava, kamen, blato)
- Material Layer Blend — logika mešanja između slojeva
Material Layer
Material Layer je specijalna vrsta Material Function koja ima punu definiciju površine (Base Color, Normal, Roughness, itd.). Kreira se kao poseban asset:
Content Browser → desni klik → Materials & Textures → Material Layer
Unutar Material Layer-a definišete kompletan izgled jednog materijala:
- Teksturno uzorkovanje
- Tiling i detail mapping
- Parametri specifični za taj sloj
- Sve kalkulacije potrebne za taj tip površine
Material Layer Blend
Material Layer Blend je još jedna specijalna Material Function koja definiše kako se dva sloja mešaju:
Content Browser → desni klik → Materials & Textures → Material Layer Blend
Tipični blend modovi:
- Height-based blending — koristi height map za prirodne prelaze (sneg se skuplja na vrhovima)
- Slope-based blending — koristi nagib površine (trava na ravnom, stene na strmom)
- Vertex color blending — koristi vertex boje za ručno slikane tranzicije
- World-space masks — koristi world poziciju za blending
22.4.3 Postavljanje Layered Materijala
Kreiranje layered materijala ide ovako:
-
Kreirate parent materijal sa Material Attributes (umesto standardnih izlaza)
- Otvorite materijal
- U Details panelu:
Use Material Attributes = true
-
Dodajte Material Layer čvorove u graf:
[Material Layer: ML_Grass] ---→ [BlendMaterialAttributes] ---→ [Material Attributes Output] [Material Layer: ML_Rock] ---→ / [Material Layer Blend: MLB_HeightBlend] ---→ / -
Svaki layer automatski doprinosi sve potrebne atribute (Base Color, Normal, Roughness, itd.)
-
Blend definiše alpha masku za mešanje
22.4.4 Primer: Teren sa Tri Sloja
Recimo da pravite teren sa travom, blatom i stenom:
ML_Grass (Material Layer):
- Albedo: T_Grass_BaseColor (tiling 4x)
- Normal: T_Grass_Normal
- Roughness: 0.8
- Parametar: GrassTint (Vector)
- Parametar: GrassTiling (Scalar)
ML_Dirt (Material Layer):
- Albedo: T_Dirt_BaseColor (tiling 6x)
- Normal: T_Dirt_Normal
- Roughness: 0.9
- Parametar: DirtDarkness (Scalar)
ML_Rock (Material Layer):
- Albedo: T_Rock_BaseColor (tiling 2x)
- Normal: T_Rock_Normal
- Roughness: 0.6
- Metallic: 0.0
- Parametar: RockWeathering (Scalar)
MLB_HeightBlend (Material Layer Blend):
- Input: Height map iz oba sloja
- Lerp sa contrast-podesivim height-based blending-om
- Parametar: BlendSharpness (Scalar)
- Parametar: HeightOffset (Scalar)
Konačni materijal:
ML_Grass ──→ BlendMaterialAttributes ──→ BlendMaterialAttributes ──→ Output
ML_Dirt ──→ / /
MLB_HeightBlend ──/ /
ML_Rock ──→────────────────────────────/
MLB_SlopeBlend ──→────────────────────/
22.4.5 Prednosti Material Layers sistema
- Modularnost — svaki sloj je nezavisan asset. Možete ga koristiti u više materijala.
- Održivost — promenite ML_Rock jednom, promeni se svuda gde se koristi.
- Preglednost — umesto ogromnog nerazumljivog grafa, imate jasno odvojene module.
- Reusability — isti Material Layer za teren, za zidove, za stene u pećini.
- Instanciranje — svaki Layer ima svoje parametre koji se mogu menjati u Material Instance-u.
22.4.6 Material Layers vs Ručno Blendovanje
| Aspekt | Ručno blendovanje | Material Layers |
|---|---|---|
| Preglednost grafa | Loša (haos za 3+ sloja) | Dobra (modularna) |
| Reusability | Nikakva (copy-paste) | Odlična (shared assets) |
| Održavanje | Teško | Lako |
| Performanse | Identične* | Identične* |
| Fleksibilnost | Potpuna | Visoka (ali struktuirana) |
*Material Layers sistem generiše ekvivalentan HLSL kod kao ručno blendovanje — nema runtime overhead-a od samog sistema. Razlika je čisto u organizaciji.
22.5 Substrate — Novi Model Materijala u UE5.x
22.5.1 Šta je Substrate?
Substrate (ranije poznat kao Strata tokom razvoja) je potpuno novi material model uveden u UE5.1+ koji zamenjuje tradicionalni fiksni sistem modela osvetljavanja (Shading Models) sa fleksibilnim, slojevitim pristupom opisu materijala.
U tradicionalnom UE5 material sistemu, vi birate jedan Shading Model za ceo materijal:
- Default Lit
- Subsurface
- Clear Coat
- Cloth
- itd.
Problem? Šta ako imate površinu koja je delimično metal (Default Lit) i delimično premazana lakom (Clear Coat)? Ili kožnu jaknu (Cloth) sa metalnim kopčama (Default Lit)? U starom sistemu, morali biste ili da koristite "From Material Expression" (što je skupo) ili da podelite mesh na više sekcija sa različitim materijalima.
Substrate rešava ovaj problem fundamentalno.
22.5.2 Kako Substrate Funkcioniše
Substrate uvodi koncept Slab-a — elementarne jedinice opisa materijala. Slab opisuje jedan sloj površine sa svim njegovim optičkim svojstvima:
Substrate Slab:
- Diffuse Albedo (float3)
- F0 (float3) — Fresnel reflektivnost pri normalnom uglu
- F90 (float3) — Fresnel reflektivnost pri tangencijalnom uglu
- Roughness (float)
- Anisotropy (float)
- Normal (float3)
- Emissive (float3)
- Second Roughness (float) — za dual-lobe specular
- Fuzz Amount (float) — za tkanine
- Fuzz Color (float3)
- Subsurface properties
- Glint properties
Ključna razlika: Umesto biranja predefinisanog Shading Model-a, vi kombinujete Slab-ove koristeći fizički korektne operacije.
22.5.3 Substrate Operatori
Substrate pruža operatore za kombinovanje Slab-ova:
Horizontal Blend
[Slab A: Metal] ──→ [Substrate Horizontal Blend] ──→ Output
[Slab B: Fabric] ──→ /
[Mask Texture] ──→ / (alpha)
Horizontalno mešanje — kao klasičan Lerp. Na jednom delu površine je metal, na drugom tkanina. Maska definiše gde je šta.
Vertical Layer
[Slab A: Clear Coat] ──→ [Substrate Vertical Layer] ──→ Output
[Slab B: Car Paint] ──→ /
Vertikalno slaganje — jedan materijal je iznad drugog. Clear coat iznad boje automobila. Substrate automatski računa fizički korektno prelamanje svetlosti između slojeva — Fresnel efekti, apsorpcija, itd.
Add
[Slab A] ──→ [Substrate Add] ──→ Output
[Slab B] ──→ /
Aditivno kombinovanje — dodaje emissive ili specijalne efekte.
Weight
[Slab A] ──→ [Substrate Weight] ──→ Output
[Weight Value] ──→ /
Skalira doprinos Slab-a — korisno za fadeout efekte.
22.5.4 Substrate vs Legacy Sistem — Konkretna Poređenja
Primer 1: Auto lak
Legacy sistem:
Shading Model: Clear Coat
- Base Color: boja automobila
- Clear Coat: 1.0
- Clear Coat Roughness: 0.05
Ograničenje: Clear Coat Shading Model ima fiksne pretpostavke o debljini i indeksu prelamanja laka.
Substrate:
Bottom Slab: Car paint
- Diffuse Albedo: boja automobila
- F0: metallic paint reflectance
- Roughness: 0.3
Top Slab: Clear coat
- F0: (0.04, 0.04, 0.04) — standardan IOR za lak
- Roughness: 0.02
- Thickness: podešljivo
Operator: Vertical Layer (Top over Bottom)
Prednost: potpuna kontrola nad svakim slojem, fizički korektan Fresnel na interfejsu između slojeva.
Primer 2: Zarđali metalni oklop sa tkaninom ispod
Legacy sistem: Nemoguće u jednom materijalu bez "From Material Expression" hack-a.
Substrate:
Slab A: Clean Metal (Metallic, low roughness)
Slab B: Rusty Metal (Non-metallic, high roughness)
Slab C: Cloth (Fuzz amount, cloth-like response)
Blend 1: Horizontal Blend (A, B, rust_mask) — čist i zarđali metal
Blend 2: Horizontal Blend (Blend1, C, cloth_mask) — metal i tkanina
Sve u jednom materijalu, sa fizički korektnim osvetljenjem za svaki deo.
22.5.5 Substrate — Slab-Based Material Description
U Substrate sistemu, Slab nije samo lista parametara — on predstavlja fizički model interakcije svetlosti sa materijalom. Svaki Slab implicitno definiše:
- BRDF (Bidirectional Reflectance Distribution Function) za refleksiju
- BTDF (Bidirectional Transmittance Distribution Function) za transmisiju
- Apsorpcioni koeficijent za volumetrijsku apsorpciju unutar sloja
- Scattering svojstva za subsurface transport
Kada koristite Vertical Layer operator, Substrate automatski računa:
- Koliko svetlosti se reflektuje sa gornjeg sloja (Fresnel)
- Koliko svetlosti prolazi kroz gornji sloj (transmisija)
- Koliko se apsorbuje prolazeći kroz debljinu gornjeg sloja (Beer-Lambert zakon)
- Kako preostala svetlost interaguje sa donjim slojem
- Koliko svetlosti sa donjeg sloja prolazi nazad kroz gornji sloj
Ovo je fizički korektan model koji bi u legacy sistemu zahtevao ručnu implementaciju svih ovih kalkulacija — a i tada ne bi bio tačan jer bi ignorisao interakcije između slojeva.
22.5.6 Aktiviranje Substrate-a
Substrate se aktivira na nivou projekta:
Project Settings → Engine → Rendering → Substrate → Enable Substrate: true
UPOZORENJE: Aktiviranje Substrate-a je jednosmerna odluka za projekat:
- Svi postojeći materijali moraju biti konvertovani
- Material Editor UI se fundamentalno menja
- Main Material Node izlazi se zamenjuju Substrate izlazima
- Ne možete mešati legacy i Substrate materijale u istom projektu
22.5.7 Performansne Implikacije Substrate-a
Substrate nije besplatan. Evo realističnog pregleda:
Veći G-Buffer: Substrate zahteva više prostora u G-Buffer-u za čuvanje dodatnih parametara (F0, F90, fuzz, thickness, itd.). Ovo znači veću bandwidth potrošnju.
Kompleksniji lighting pass: Fizički koreknto mešanje slojeva zahteva dodatne kalkulacije u lighting shader-u.
Veća shader kompleksnost: Svaki Slab dodaje instrukcije. Materijal sa 3 vertikalna sloja je značajno skuplji od single-slab materijala.
Ali:
- Epic je uložio značajan napor u optimizaciju — single-slab Substrate materijali su performansno uporedivi sa legacy materijalima
- Complexity je "pay for what you use" — jednostavni materijali su jeftini, kompleksni su skuplji
- Za AAA projekte sa visokim vizuelnim zahtevima, prednosti vizuelnog kvaliteta opravdavaju cenu
22.5.8 Kada Koristiti Substrate vs Legacy
| Scenario | Preporuka |
|---|---|
| Novi projekat, AAA kvalitet | Substrate |
| Novi projekat, mobilna platforma | Legacy (manja cena) |
| Postojeći projekat sa mnogo materijala | Legacy (konverzija je skupa) |
| Projekt koji zahteva mešanje shading modela | Substrate |
| Jednostavna stilizovana grafika | Legacy |
| Realistični automobili, nakit, koža | Substrate (drastično bolje) |
| VR projekt (performance-critical) | Legacy (svaki frame ms je bitan) |
22.6 Shader Kompilacija i PSO Caching
22.6.1 Od Material Grafa do GPU Shadera
Kada kliknete "Apply" u Material Editor-u, pokreće se složen proces kompilacije. Razumevanje ovog procesa je ključno za upravljanje compile time-ovima i sprečavanje runtime hitch-eva.
Korak 1: Material Graph → HLSL UE5 Material Compiler traversira graf i generiše platformski nezavisni HLSL kod. Ovo je relativno brz proces (sekunde).
Korak 2: HLSL → Shader Permutacije Jedan materijal se kompajlira u mnogo shader varijanti, jer mora da podrži različite konfiguracije renderovanja:
Permutacije uključuju:
× Vertex Factory (Static Mesh, Skeletal Mesh, Landscape, Niagara, itd.)
× Lighting konfiguracija (stationary, movable, no lights)
× Shadow modovi
× Feature levels
× Static switch kombinacije
× Quality levels
× Platform-specifične varijacije
= STOTINE do HILJADE permutacija po materijalu!
Korak 3: HLSL → Platform Bytecode Svaka HLSL permutacija se kompajlira u platformski specifičan format:
- Windows DX12: DXBC ili DXIL bytecode
- Windows Vulkan: SPIR-V
- macOS/iOS: Metal Intermediate Representation (Metal AIR)
- PlayStation 5: PSSL bytecode
- Xbox Series: DXIL
- Android: SPIR-V ili GLSL ES
Ovaj korak je CPU-intenzivan i predstavlja većinu compile time-a.
22.6.2 Derived Data Cache (DDC)
DDC je sistem keširanja kompajliranih shadera (i drugih "derived" podataka kao što su kompresovane teksture, cooked content, itd.).
Kako DDC funkcioniše:
- Pre kompilacije, UE5 izračunava hash materijala (svih čvorova, parametara, setinga)
- Proverava da li taj hash postoji u DDC-u
- Ako postoji — koristi keširanu verziju (brzo!)
- Ako ne postoji — kompajlira iznova i čuva rezultat u DDC-u
Nivoi DDC-a:
Local DDC (vaš računar)
└── Shared DDC (mrežni drive, tim deli)
└── Cloud DDC (Unreal Cloud DDC / custom S3 bucket)
- Local DDC se čuva u
[ProjectDir]/DerivedDataCache/ili na globalnom mestu - Shared DDC je mrežni folder koji ceo tim koristi — kada jedan programer kompajlira shader, svi ostali ga dobijaju iz keša
- Cloud DDC za distribuirane timove
Konfiguracija Shared DDC-a (u DefaultEngine.ini):
[DerivedDataBackendGraph]
Shared=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false,
PurgeTransient=true, DeleteUnused=true, UnusedFileAge=34,
FoldersToClean=-1, Path="\\server\share\UE5DDC",
EnvPathOverride=UE_SHARED_DDC_PATH)
22.6.3 PSO — Pipeline State Object
PSO (Pipeline State Object) je DirectX 12 / Vulkan koncept koji objedinjuje sve stanje GPU pipeline-a u jedan objekat:
PSO = {
Vertex Shader (kompajlirani bytecode)
Pixel Shader (kompajlirani bytecode)
Geometry/Hull/Domain Shader (ako postoji)
Rasterizer State (wireframe, cull mode, depth bias)
Blend State (alpha blending konfiguracija)
Depth-Stencil State
Render Target Format
MSAA konfiguracija
Input Layout (vertex format)
Root Signature / Pipeline Layout
}
Zašto je PSO bitan?
U starijim API-jima (DX11, OpenGL), GPU state se mogao menjati inkrementalno. U DX12/Vulkan, ceo pipeline state mora biti unapred kompajliran u jedan PSO objekat. Ako GPU naiđe na PSO koji nije prethodno kreiran, mora da ga kompajlira u tom trenutku — što izaziva hitch (zamrzavanje) u igri.
22.6.4 PSO Precaching — Sprečavanje Hitch-eva
UE5 nudi nekoliko mehanizama za precaching PSO-ova:
Automatsko PSO prikupljanje
- Pokrenite igru u razvojnom okruženju
- Igrajte normalno — prolazite kroz sve nivoe, koristite sve oružje, itd.
- UE5 beleži svaki PSO koji je kreiran tokom sesije
- Ti PSO-ovi se čuvaju u PSO cache fajl (
*.rec.upipelinecache)
Project Settings → Engine → Rendering →
Pipeline State Object (PSO) Caching →
Share Material Shader Code: true
Shared Material Native Libraries: true
PSO Bundled Precaching
Za distribuciju:
- Prikupite PSO cache iz više sesija igranja
- Bundle-ujte ih u build:
Project Settings → Packaging → Share Material Shader Code = true Bundle PSO Cache = true - Pri pokretanju igre, UE5 učitava bundled cache i precompile-uje sve PSO-ove pre nego što se ikada koriste
Runtime PSO Precaching (UE5.3+)
UE5.3 uvodi automatsko PSO precaching koje predviđa koji PSO-ovi će biti potrebni na osnovu vidljivih objekata i priprema ih unapred:
Project Settings → Engine → Rendering →
PSO Precaching → Enable PSO Precaching: true
Ovo značajno smanjuje hitch-eve bez ručnog prikupljanja PSO cache-a.
22.6.5 Cook-Time vs Runtime Kompilacija
Cook-time kompilacija (za distribuciju):
- Svi materijali se kompajliraju tokom cook procesa (
File → Package Project) - Shadera se kompajliraju za ciljnu platformu
- Rezultat se pakuje u finalni build
- Nema runtime kompilacije — sve je spremno pre pokretanja igre
- Problem: cook može trajati satima za veliki projekat
Runtime kompilacija (u editoru):
- Shadera se kompajliraju "on demand" — kada se materijal prvi put koristi
- Koristi se Shader Compile Worker (višenitni proces za paralelnu kompilaciju)
- Compilacija se prikazuje u donjem desnom uglu editora: "Compiling Shaders (1523)"
- Nekompajlirani materijali prikazuju default materijal (sivi šah)
Shader Compile Worker konfiguracija:
[DevOptions.Shaders] u ConsoleVariables.ini:
r.ShaderCompiler.NumWorkers=8 ; Broj paralelnih worker procesa
r.ShaderCompiler.JobsPerWorker=32 ; Poslova po worker-u
Na mašinama sa mnogo jezgara (16+), povećanje broja worker-a dramatično ubrzava kompilaciju.
22.6.6 Upravljanje Shader Compile Time-ovima
Kompilacija shadera može biti ogroman bottleneck u produkciji. Evo praktičnih saveta:
1. Koristite Shared DDC: Najveća ušteda. Kad jedan član tima kompajlira shader, svi ostali ga dobijaju iz keša.
2. Minimizirajte Static Switch-eve: Svaki Static Switch udvostručuje broj permutacija. 10 switch-eva = 1024 permutacije!
3. Koristite Material Instance-e agresivno: Instance ne generišu nove permutacije.
4. Batched shader compilation:
Editor Preferences → Shader Compilation →
"Compile Shaders for Development" = false (samo za shipping platforme)
5. Monitoring:
stat shadercompiling— konzolna komanda za praćenje kompilacije- Shader Stats panel u Material Editor-u prikazuje instruction count po permutaciji
r.ShaderCompiler.DumpJobLog=1— loguje sve shader compile poslove
6. On-demand shader compilation: Umesto da kompajlirate sve permutacije odmah, UE5 može da kompajlira samo one koje su zaista potrebne:
r.Shaders.LazyCompilation=1
Ovo dramatično ubrzava iteraciju u editoru, ali može izazvati hitch-eve pri prvom korišćenju materijala.
22.7 Optimizacija u Material Sistemu
22.7.1 Static Switches vs Dynamic Switches
Ovo je jedna od najvažnijih odluka koje ćete donositi pri dizajniranju materijala. Razumevanje razlike je kritično.
Static Switch Parameter
[Texture Sample A] ──→ [Static Switch Parameter: "UseDetailNormal"] ──→ [Normal]
[Texture Sample B] ──→ /
Ponašanje:
- Vrednost se postavlja u Material Instance-u u editoru
- Svaka kombinacija vrednosti generiše novu shader permutaciju
- Neaktivna grana se potpuno eliminiše iz kompajliranog shadera
- Nula runtime cost za eliminisanu granu
Kada koristiti:
- Feature koji je skup i koji mnogi instance-i neće koristiti
- Primer: Detail Normal map (skupa operacija, ali ne treba svim materijalima)
- Primer: Emissive support (dodaje instrukcije, ali većina materijala ne svetli)
Opasnost:
- N static switch-eva = 2^N potencijalnih permutacija
- 5 switch-eva = 32 permutacije — prihvatljivo
- 10 switch-eva = 1,024 permutacije — problematično
- 15 switch-eva = 32,768 permutacije — katastrofa
- Ne koristite static switch za nešto što se razlikuje u malom broju instance-ova
Dynamic Switch (If / Branch čvorovi)
[Texture Sample A] ──→ [If: ScalarParam > 0.5] ──→ [Normal]
[Texture Sample B] ──→ /
Ponašanje:
- Vrednost se može menjati runtime
- Nema novih permutacija
- Obe grane se izvršavaju na GPU-u — GPU evaluira obe strane i bira rezultat
- Ima runtime cost, ali ne dodaje nove permutacije
Kada koristiti:
- Opcije koje se menjaju runtime
- Opcije koje variraju često među instance-ima
- Kada je cena obe grane mala
Praktičan Primer
Recimo da imate master materijal za karaktere sa sledećim opcijama:
- Da li koristi detail normal? (Static Switch — skupa operacija, mali broj karaktera je koristi)
- Da li je metal ili ne-metal? (NE koristite switch! Metallic parametar je dovoljan)
- Da li ima emissive? (Static Switch — ako 80% karaktera nema emissive)
- Boja kože? (Scalar/Vector parametar — menja se u instance-u, ne treba switch)
22.7.2 Feature Level Switch
[High Quality Noise] ──→ [Feature Level Switch] ──→ [Output]
[Simple Gradient] ──→ [ES3.1 ulaz] /
Feature Level Switch vam omogućava da definišete različite grane grafa za različite platforme:
- SM5 / SM6 — Desktop (Windows, macOS)
- ES3.1 — Mobile (Android, iOS)
Svaka platforma dobija svoj optimizovani graf. Na mobilnim uređajima koristite jednostavniji shader, na desktop-u pun kvalitet.
Ovo ne stvara runtime overhead — kompajlira se samo grana za ciljnu platformu.
22.7.3 Quality Switch
[4x Texture Samples + Complex Blending] ──→ [Quality Switch] ──→ [Output]
[2x Texture Samples + Simple Blending] ──→ [Medium] /
[1x Texture Sample] ──→ [Low] /
Quality Switch vam omogućava da definišete različite kvalitete materijala za engine Quality Settings:
- Epic — full quality
- High — nešto redukovano
- Medium — srednji kvalitet
- Low — minimalan kvalitet
Igrači koji igraju na slabijim računarima biraju niži quality level, i automatski dobijaju lakše shadere.
Svaki quality level je zasebna shader permutacija — ali to je prihvatljivo jer je broj quality levela fiksan (4) i korisnik koristi samo jedan u datom trenutku.
22.7.4 Shared Material Functions
Material Functions su reusable podgrafovi koje možete koristiti u više materijala:
Content Browser → desni klik → Materials & Textures → Material Function
Kreiranje Material Function
Definišete:
- Ulaze (Function Input čvorovi) — parametri koje pozivalac prosleđuje
- Logiku — čvorovi koji obrađuju podatke
- Izlaz (Function Output čvorovi) — rezultat koji se vraća pozivaocu
Korišćenje
U bilo kom materijalu:
Desni klik → Material Function → [Ime vaše funkcije]
ili jednostavno ukucajte ime funkcije u pretragu.
Primer: MF_DetailNormal
Inputs:
- BaseNormal (float3)
- DetailNormal (float3)
- DetailIntensity (float)
Logic:
- Scale Detail Normal by Intensity
- Blend normals using RNM (Reoriented Normal Mapping)
Output:
- CombinedNormal (float3)
Ovu funkciju sada možete koristiti u svakom materijalu koji treba detail normal mapping, umesto da ponavljate istu logiku svuda.
UE5 Built-in Material Functions
UE5 dolazi sa stotinama ugrađenih Material Functions. Neke od najkorisnijih:
MF_FlattenNormal— smanjuje intenzitet normal mapeMF_CheapContrast— brza contrast korekcijaMF_BlendAngleCorrectedNormals— pravilno blendovanje normalaMF_ObjectScale— vraća scale aktoraMF_Wind— simulacija vetra za vegetacijuMF_Fresnel— custom Fresnel efekatMF_RadialGradient— radijalni gradijent
Pregledajte ih u Material Editor-u pod kategorijom "Material Functions" — mnoge česte operacije su već implementirane i optimizovane.
22.7.5 Instruction Count Monitoring
Instruction count je primarna metrika za kompleksnost materijala. Manje instrukcija = brže renderovanje (generalno).
Gde videti Instruction Count
U Material Editor-u:
- Stats panel (Window → Stats) — prikazuje instruction count za sve permutacije
- Tooltip na Main Material Node — prikazuje zbirne informacije
- Viewport → Optimization Viewmodes → Shader Complexity — vizuelizuje kompleksnost na sceni
Instruction Count preporuke
| Platforma | Base Pass | Preporuka |
|---|---|---|
| High-end PC | Pixel Shader | < 200 instrukcija |
| Mid-range PC | Pixel Shader | < 150 instrukcija |
| Current-gen konzole | Pixel Shader | < 150 instrukcija |
| Mobile (high) | Pixel Shader | < 100 instrukcija |
| Mobile (low) | Pixel Shader | < 60 instrukcija |
| VR | Pixel Shader | < 100 instrukcija (×2 oka!) |
Vertex shader instrukcije su obično manje bitne jer ih ima mnogo manje od piksela, ali i dalje treba paziti sa World Position Offset kalkulacijama.
Smanjenje Instruction Count-a
1. Smanjite texture sample-ove: Svaki texture sample košta ~4-8 instrukcija + bandwidth. Pakovati podatke:
ORM tekstura: R = Ambient Occlusion, G = Roughness, B = Metallic
Jedan uzorak umesto tri!
2. Izbegavajte nepotrebne operacije:
// LOŠ: Multiply pa Divide istim brojem
Texture → Multiply(2.0) → Divide(2.0) → Output // Beskorisno!
// DOBAR: Eliminišite redundantne operacije
Texture → Output
3. Koristite konstantne fold-ove:
// LOŠ: Runtime kalkulacija konstanti
Constant(2.0) → Multiply → Constant(3.0) → Multiply → Output
// Ovo generiše 2 multiply instrukcije
// DOBAR: Preračunajte konstante
Constant(6.0) → Multiply → Output
// Jedna multiply instrukcija
UE5 compiler često automatski radi constant folding, ali ne uvek — pogotovo kada su čvorovi razdvojeni.
4. Koristite aproximacije umesto tačnih kalkulacija:
// SKUPO: pow(x, 2.2) — full power function
// JEFTINO: x * x — dobar "eyeball" approximation za gamma ~2.0
5. Koristite Fully Rough flag:
Material Properties → Fully Rough = true
Ako materijal ne treba specular lighting (npr. trava, zemlja, stilizovani materijali), uključite Fully Rough. Ovo eliminiše ceo specular pipeline i štedi ~20 instrukcija.
6. Koristite Disable Depth Test i No Lightmap za jednostavne materijale:
Manje feature = manje instrukcija.
22.7.6 Napredne Optimizacione Tehnike
Texture Atlasing za Materijale
Umesto mnogo malih tekstura, koristite jedan atlas:
Atlas 2048×2048 sa UV offsetom:
Material A: UV × (0.5, 0.5) + (0.0, 0.0) → gornji-levi kvadrant
Material B: UV × (0.5, 0.5) + (0.5, 0.0) → gornji-desni kvadrant
Material C: UV × (0.5, 0.5) + (0.0, 0.5) → donji-levi kvadrant
Material D: UV × (0.5, 0.5) + (0.5, 0.5) → donji-desni kvadrant
Prednost: jedan texture bind umesto četiri = manje state change-ova.
Distance-Based Material LOD
Koristite rastojanje od kamere za smanjenje kompleksnosti:
[Camera Distance] → [Divide by MaxDistance] → [Clamp 0-1] → Lerp Alpha
[Full Detail Normal + Height Blend] → [Lerp] → [Output]
[Simple Flat Normal] → /
Na velikim rastojanjima, kompleksne kalkulacije se zamenjuju jednostavnim — igrač ionako ne vidi razliku.
Per-Instance Custom Data
Za instance-ovane mesheve (Instanced Static Mesh, Hierarchical Instanced Static Mesh), koristite Per Instance Custom Data umesto DMI-ova:
// U Blueprint-u ili C++:
ISMComponent->SetCustomDataValue(InstanceIndex, DataIndex, Value);
U materijalu:
[PerInstanceCustomData] → čvor koji čita custom data za svaku instancu
Ovo je daleko efikasnije od kreiranja DMI-a za svaku instancu — jedan shader, jedan draw call (instanced), različiti parametri po instanci.
Shader Complexity Viewmode
Koristite Optimization Viewmodes → Shader Complexity u Viewport-u za vizuelnu inspekciju:
- Zeleno — jeftin materijal (mali broj instrukcija)
- Crveno — skup materijal (mnogo instrukcija)
- Belo/Ružičasto — previsoka kompleksnost (potrebna optimizacija)
Overdraw (preklapanje transparentnih objekata) je posebno vidljiv — oblasti gde se mnogo transparentnih objekata preklapa postaju izuzetno crvene.
22.7.7 Nanite i Materijali — Posebna Razmatranja
Nanite (o kome ste čitali u ranijim poglavljima) ima specifične zahteve za materijale:
Nanite podržava:
- Opaque materijale (potpuna podrška)
- Masked materijale (od UE5.1+, sa izvesnim ograničenjima)
- World Position Offset (od UE5.1+, mora se eksplicitno uključiti)
Nanite NE podržava:
- Translucent materijale
- Materijale sa custom vertex animacijama (osim WPO)
- Tessellation (Nanite je zamena za tessellation)
Optimizacija za Nanite:
- Nanite rasterizuje kroz software rasterizer za male trouglove i hardware rasterizer za velike
- Material evaluation se dešava samo za vidljive piksele (visibility buffer pristup)
- Ovo znači da pixel shader cost postaje manje bitan za occluded geometriju
- Ali vertex shader (WPO) i dalje utiče na sve trouglove u Nanite cluster-u
Praktičan savet: Za Nanite mesheve, fokusirajte optimizaciju na pixel shader jer vertex shader deo uglavnom ne postoji u tradicionalnom smislu — Nanite ima svoj rasterization pipeline.
22.8 Praktični Workflow — Od Koncepta do Optimizovanog Materijala
Da sumiramo sve što smo naučili, evo preporučenog workflow-a za kreiranje materijala u produkcijskom okruženju:
Korak 1: Planirajte Material Hijerarhiju
Pre nego što otvorite Material Editor, odgovorite na pitanja:
- Koliko master materijala vam treba? (Cilj: što manje)
- Koje parametre će imati? (Samo ono što se zaista menja između instance-a)
- Koji static switch-evi su potrebni? (Samo za skupe opcije)
- Da li su MPC-ovi potrebni? (Za globalne efekte)
Korak 2: Kreirajte Material Functions
Identifikujte zajedničke operacije i napravite reusable Material Functions:
- Detail normal blending
- Triplanar projection
- Height-based layer blending
- Distance-based detail fade
- Wind animation
Korak 3: Izgradite Master Material
- Kreirajte materijal sa svim potrebnim parametrima
- Organizujte parametre u grupe (Group property na svakom parametru):
- "01 - Base Color"
- "02 - Normal"
- "03 - Surface Properties"
- "04 - Emissive"
- "05 - Detail"
- Postavite razumne default vrednosti
- Dodajte static switch-eve za opcione feature-e
- Koristite Quality Switch za skalabilnost
- Koristite Comment čvorove za dokumentovanje grafa
Korak 4: Instancirajte
- Kreirajte Material Instance-e za svaku varijaciju
- Override-ujte samo parametre koji se razlikuju od default-a
- Koristite hijerarhiju instance-a za organizaciju
Korak 5: Optimizujte
- Proverite instruction count (Stats panel)
- Pokrenite Shader Complexity viewmode
- Profilirajte sa GPU profiler-om (Poglavlje 21)
- Identifikujte i eliminišite bottleneck-ove
- Testirajte na target hardveru
Korak 6: Testirajte PSO Caching
- Pokrenite igru i prolazite kroz sve scenarije
- Prikupite PSO cache
- Bundle-ujte u shipping build
- Verifikujte da nema hitch-eva
22.9 Česte Greške i Kako Ih Izbeći
Greška 1: Previše zasebnih materijala umesto instance-a
Simptom: Duge kompilacije, veliki shader memory footprint, česti GPU state change-ovi. Rešenje: Konsolidujte u master materijale + instance. Kao referenca — AAA projekti obično imaju manje od 50 master materijala za celu igru.
Greška 2: Static Switch eksplozija
Simptom: Hiljade shader permutacija, kompilacija traje satima. Rešenje: Ograničite static switch-eve na 4-6 po materijalu. Koristite dynamic branching za manje skupe opcije.
Greška 3: Kreiranje DMI-a svakog frame-a
Simptom: Memory leak, sve lošije performanse tokom vremena. Rešenje: Kreirajte DMI jednom u BeginPlay, zatim samo ažurirajte parametre.
Greška 4: Ignoring instruction count na mobilnim platformama
Simptom: Materijali savršeno rade na PC-u, ali mobile FPS padne na 15. Rešenje: Koristite Quality Switch za mobile verzije. Testirajte na target hardware-u rano i često.
Greška 5: Transparentni materijali svuda
Simptom: Masivan overdraw, katastrofalne performanse na scenama sa vegetacijom. Rešenje: Koristite Masked umesto Translucent gde je moguće. Za vegetaciju, koristite Masked blend mode sa Two Sided Foliage shading model-om.
Greška 6: Previše teksturnih uzorkovanja
Simptom: Visok texture bandwidth, dugačak pixel shader, bottleneck na memory. Rešenje: Pakujte podatke u kanale (ORM tekstura), koristite texture atlase, implementirajte distance-based LOD za teksture.
Greška 7: Nekorišćenje DDC-a
Simptom: Svaki član tima kompajlira sve shadere iznova. Rešenje: Postavite shared DDC na mrežni drive. Ovo je jedan od najlakših načina za dramatično ubrzavanje workflow-a celog tima.
22.10 Rezime Poglavlja
U ovom poglavlju smo detaljno pokrili celokupan UE5 Material System:
-
Material Graph je moćna apstrakcija nad raw HLSL kodom koja omogućava vizuelno kreiranje shadera sa automatskom cross-platform kompilacijom i optimizacijom.
-
Material Instance-i su apsolutno kritični za performanse — razdvajaju shader logiku od parametarskih podataka, eliminišu shader permutation explosion, i dramatično smanjuju GPU state change-ove.
-
Material Parameter Collections omogućavaju globalne parametre deljene između svih materijala — idealno za ambijentalne efekte kao što su vetar, doba dana, i interakcija sa igračem.
-
Material Layers donose modularnost u dizajn kompleksnih površina — svaki sloj je nezavisan asset koji se može ponovo koristiti.
-
Substrate predstavlja budućnost UE5 material sistema sa fizički korektnim slojevitim materijalima koji prevazilaze ograničenja fiksnih shading modela.
-
Shader kompilacija i PSO caching su kritični za isporuku bez hitch-eva — razumevanje DDC-a, permutacija, i PSO precaching-a je neophodno za produkcijski workflow.
-
Optimizacija se svodi na mudro korišćenje static/dynamic switch-eva, smanjenje instruction count-a, pakovanje tekstura, i konstantno profilisanje.
Tabela Ključnih Termina
| Termin (EN) | Objašnjenje |
|---|---|
| Material Graph | Vizuelni node-based editor za kreiranje shadera |
| Material Instance | Varijacija materijala koja deli shader sa parent materijalom, menjajući samo parametre |
| Material Instance Constant (MIC) | Material Instance kreiran u editoru, bez runtime overhead-a |
| Dynamic Material Instance (DMI) | Material Instance kreiran u runtime-u, parametri se mogu menjati tokom igre |
| Material Parameter Collection (MPC) | Globalni set parametara dostupan svim materijalima |
| Material Function | Reusable podgraf koji se može koristiti u više materijala |
| Material Layer | Modularna definicija jednog materijala za upotrebu u layered sistemu |
| Material Layer Blend | Funkcija koja definiše kako se dva Material Layer-a mešaju |
| Substrate (Strata) | Novi slab-based material model u UE5 za fizički korektno slojevite materijale |
| Slab | Osnovna jedinica opisa površine u Substrate sistemu |
| Static Switch | Parametar koji bira granu grafa u compile-time, generiše novu permutaciju |
| Dynamic Branch | Runtime grananje u shaderu, obe grane se evaluiraju |
| Shader Permutation | Jedna varijanta kompajliranog shadera za specifičnu konfiguraciju |
| PSO (Pipeline State Object) | Objekat koji objedinjuje celokupno stanje GPU renderovnog pipeline-a |
| PSO Precaching | Unapred kompajliranje PSO-ova da bi se sprečili runtime hitch-evi |
| DDC (Derived Data Cache) | Keš sistem za kompajlirane shadere i druge izvedene podatke |
| Instruction Count | Broj GPU instrukcija u kompajliranom shaderu — mera kompleksnosti |
| Constant Folding | Compiler optimizacija koja preračunava konstantne izraze u compile-time |
| Feature Level Switch | Čvor koji bira različite grane grafa za različite platforme (SM5, ES3.1) |
| Quality Switch | Čvor koji bira granu grafa prema postavljenom quality level-u (Low/Med/High/Epic) |
| ORM Texture | Pakovanje Ambient Occlusion, Roughness i Metallic u R, G, B kanale jedne teksture |
| Vertex Factory | UE5 koncept koji definiše format i izvor vertex podataka (Static Mesh, Skeletal, itd.) |
| World Position Offset (WPO) | Material izlaz koji pomera vertex pozicije — koristi se za animaciju vegetacije, talasa, itd. |
| Per Instance Custom Data | Efikasan način prosleđivanja jedinstvenih parametara instanciranim meshevima |
Preporučeno Čitanje i Resursi
Unreal Engine Dokumentacija
- Materials — Zvanična dokumentacija za material sistem
- Material Instances — Detaljan vodič za material instance
- Material Parameter Collections — MPC dokumentacija
- Substrate — Substrate (Strata) dokumentacija
- PSO Caching — Pipeline State Object caching vodič
- Shader Development — Shader razvoj za napredne korisnike
Dodatni Resursi
- Epic Games Tech Blog — Redovni članci o novim material features
- Unreal Engine Community Wiki — Zajednica deli korisne Material Function-e
- GDC / Unreal Fest prezentacije — Duboki tehnikalni dive-ovi u material pipeline
- Ryan Brucks materijal tutoriali — Izuzetan izvor za napredne material tehnike
Poglavlja za Cross-Reference
- Poglavlje 17: Shader programiranje — HLSL osnove, shader pipeline, custom shader code
- Poglavlje 18: Modeli materijala — PBR teorija, BRDF-ovi, shading modeli detaljno
- Poglavlje 21: Shader optimizacija — GPU profilisanje, ALU vs bandwidth vs latency, occupancy
U sledećem poglavlju prelazimo na post-processing pipeline — kako efekti poput bloom-a, tone mapping-a, i motion blur-a transformišu vašu renderovanu sliku u finalni vizuelni rezultat.