Poglavlje 37: Asset Pipeline

Poglavlje 37: Asset Pipeline

U ovom poglavlju ucite sve o procesu koji se desava pre nego sto ijedan piksel bude renderovan -- kako sadrzaj (modeli, teksture, zvuk, animacije) prelazi put od alata za kreiranje do engine-a u optimizovanom obliku. Razumecete zasto los asset pipeline unistava performans pre nego sto rendering uopste pocne, kako pravilno importovati razlicite tipove asset-a, kako funkcionisu LOD sistemi i mesh redukcija, kako odabrati ispravnu kompresiju tekstura, kako pronaci problematicne asset-e u projektu, i koje best practice treba slediti da biste odrzali projekat zdravim od prvog dana do isporuke.


Zasto ovo poglavlje postoji

Zamislite sledeci scenario: vas 3D umetnik je napravio prelepu zgradu u Blenderu. Model izgleda fantasticno -- 2 miliona trouglova, 4K teksture za svaki materijal, savrsene normale. Importujete ga u UE5, stavite u scenu, i... performans pada na kolena.

Ali zasto? Zgrada izgleda identicno u Blenderu na 60 FPS. Problem je sto Blender renderuje jednu zgradu. Vasa igra ima 200 takvih zgrada, plus teren, plus vegetaciju, plus likove, plus efekte. I niste podesili LOD-ove. I teksture su nekompresovane. I mesh ima 500.000 verteksa koje niko nikada nece videti jer su na unutrasnjim stranama koje igrac nikada ne gleda.

Asset pipeline je proces koji premoscuje jaz izmedju "izgleda lepo u alatu za kreiranje" i "radi efikasno u engine-u". To nije jedan korak -- to je citav lanac odluka i transformacija:

[DCC alat] --> [Export] --> [Import u UE5] --> [Processing] --> [Cooking] --> [Runtime]
  Blender       FBX          Import settings    LOD generacija   Kompresija   Renderovanje
  Maya           USD          Validacija         Mesh redukcija   Pakovanje    Streaming
  ZBrush        glTF         Organizacija       Tex kompresija   Enkodiranje  Memory mgmt
  Substance                                     Collision gen.

Svaki korak u ovom lancu moze da unese probleme ili da ih resi. Cilj ovog poglavlja je da razumete svaki korak, prepoznate ceste greske, i uspostavite pipeline koji proizvodi optimizovane asset-e od samog pocetka.

Zasto je ovo bitno pre renderinga?

U prethodnim poglavljima (poglavlje 07 -- render pipeline, poglavlje 30 -- Nanite, poglavlje 29 -- UE5 rendering arhitektura) govorili smo o tome kako engine renderuje scenu. Ali rendering moze da radi samo sa onim sto mu date. Ako mu date mesh sa 5 miliona trouglova za objekat koji ce na ekranu biti 30 piksela velik, rendering nema sta da uradi -- morate te trouglove procesirati, bez obzira koliko su besmisleni.

Los asset pipeline je kao da kuhinji dostavite sirove, neociscene namirnice i ocekujete da jelo bude gotovo za 5 minuta. Dobar pipeline je kao da dostavite pripremljene, porcionirane sastojke -- kuhinja (rendering) moze da radi efikasno jer je posao pripreme vec obavljen.


37.1 Import Process

37.1.1 FBX Import -- Meshevi, Skeleti, Animacije

FBX (Filmbox) format je de facto standard za razmenu 3D sadrzaja izmedju DCC (Digital Content Creation) alata i game engine-a. Autodesk je razvio ovaj format, i UE5 ga koristi kao primarni format za import mesh-eva, skeleta i animacija.

Kako FBX import radi u UE5

Kada importujete FBX fajl u UE5, engine ga parsira i kreira odgovarajuce UE5 asset-e:

  1. Static Mesh -- za staticne objekte bez animacije
  2. Skeletal Mesh -- za objekte sa skeletom (kosti/bones)
  3. Animation Sequence -- za animacione podatke
  4. Physics Asset -- za fizicku reprezentaciju skeletal mesh-a
  5. Skeleton -- za definiciju kostiju i hijerarhije
FBX fajl
├── Geometry data     --> Static Mesh ili Skeletal Mesh
├── Material data     --> Material slots (UE5 pravi placeholder materijale)
├── Skeleton data     --> Skeleton asset
├── Animation data    --> Animation Sequence(s)
├── Morph targets     --> Blend Shapes
└── Collision data    --> Collision primitives (ako su definisani)

Static Mesh Import -- kljucna podesavanja

Kada importujete static mesh, UE5 vam prikazuje Import Options dijalog sa mnogo podesavanja. Evo onih koja direktno uticu na performans:

Transform sekcija:

Podesavanje Sta radi Performansni uticaj
Import Uniform Scale Skalira mesh tokom importa Nikakav runtime uticaj, ali pogresen scale moze da zahteva transform u runtime-u
Convert Scene Unit Konvertuje jedinice iz DCC alata u UE5 (centimetri) Nikakav, ali pogresen scale pravi probleme sa fizikom i LOD-ovima
Force Front X Axis Rotira mesh da X bude "napred" Nikakav runtime uticaj

Mesh sekcija:

Podesavanje Sta radi Performansni uticaj
Auto Generate Collision Automatski generise koliziju Moze kreirati nepotrebno slozenu koliziju -- vidi poglavlje 36
Generate Lightmap UVs Automatski generise UV kanal za lightmap Dodaje UV set (memorija), ali je neophodan za baked osvetljenje
Transform Vertex to Absolute Prebacuje vertex pozicije u apsolutni prostor Moze povecati preciznost, minimalan performansni uticaj
Combine Meshes Spaja vise mesh-eva iz FBX-a u jedan Smanjuje draw call-ove, ali gubi granularnost za culling
Remove Degenerates Brise degenerisane trouglove (nulte povrsine) Smanjuje nepotrebnu geometriju

Build sekcija:

Podesavanje Sta radi Performansni uticaj
Build Nanite Omogucava Nanite za ovaj mesh Krucijalan za high-poly mesh-eve -- vidi poglavlje 30
Build Reversed Index Buffer Kreira reverzni index buffer za two-sided renderovanje Duplira geometriju za rendering sa obe strane
Compute Weighted Normals Racuna normale tezinski na osnovu povrsine trouglova Bolji kvalitet normala, minimalan overhead
Threshold Position/UV Pragovi za welding verteksa Manji pragovi = vise verteksa = vise memorije, ali vise preciznosti

Primer ispravnog importa staticnog mesh-a:

Preporucena podesavanja za tipican prop:
- Auto Generate Collision: ON (ali proverite rezultat!)
- Generate Lightmap UVs: ON (ako koristite baked lighting)
- Build Nanite: ON (za mesh-eve sa >10K trouglova, ako zadovoljavaju Nanite uslove)
- Combine Meshes: OFF (osim ako zaista zelite jedan mesh)
- Remove Degenerates: ON (uvek)
- Normal Import Method: Import Normals and Tangents (sacuvajte DCC normalne)

Skeletal Mesh Import -- posebne napomene

Skeletal mesh-evi imaju dodatne opcije koje uticu na performans:

Skeleton:

Bone Count: Svaki bone u skeletu ima CPU cost jer se transformacije racunaju na CPU-u (Game Thread). Tipicni budzeti:

Tip lika Preporuceni max bones
Glavni igrac (AAA) 150-300
NPC-ovi (srednji detalj) 80-150
NPC-ovi u pozadini 30-60
Zivotinje/Creatures 50-120
Prosti objekti 10-30
// Mozete programski proveriti broj kostiju skeletal mesh-a
int32 BoneCount = SkeletalMesh->GetRefSkeleton().GetNum();
UE_LOG(LogTemp, Warning, TEXT("Mesh %s ima %d kostiju"), *SkeletalMesh->GetName(), BoneCount);

LOD za Skeletal Mesh: Za razliku od static mesh-eva, skeletal mesh LOD-ovi mogu da redukuju i broj kostiju -- nizji LOD nivo koristi manji skeleton, sto smanjuje CPU cost transformacija.

Animacije -- Import podesavanja

Animacije se importuju iz FBX fajlova kao Animation Sequence asset-i. Kljucna podesavanja:

Primer: Animacija hoda od 2 sekunde
- Na 30 FPS: 60 frejmova x 100 kostiju x 3 kanala (pos, rot, scale) = 18,000 kljuceva
- Na 120 FPS: 240 frejmova x 100 kostiju x 3 kanala = 72,000 kljuceva
- Sa Remove Redundant Keys: mozda samo 5,000-8,000 kljuceva

Razlika u memoriji: 72,000 vs 8,000 kljuceva. Skoro 10x.

37.1.2 Texture Import -- Formati i Kompresija

Teksture su tipicno najveci potrosac memorije u igri -- i na disku i u VRAM-u. Kako ih importujete i koja podesavanja odaberete ima drastican uticaj na performans.

Source formati

UE5 podrzava import sledecih formata:

Format Za sta se koristi Napomene
PNG Opsta namena, lossless Dobar za import, engine ce rekompresovati
TGA Opsta namena, uncompressed Tradicionalni game dev format
TIFF High-end, HDR, 16/32-bit Za precizne podatke (height map, HDR)
EXR HDR, linearan prostor boja Za HDRI environment mape, light bake podatke
JPEG Lossy, mala velicina fajla Izbegavajte za normal mape i maske (lossy artefakti)
BMP Nekompresovan Veliki fajlovi, nema prednosti
PSD Photoshop native UE5 moze direktno da cita PSD fajlove
HDR Radiance format Za environment mape

Vazan koncept: Format u kome importujete teksturu nije isti format koji ce se koristiti u runtime-u. UE5 rekompresuje svaku importovanu teksturu u odgovarajuci GPU format (BC, ASTC, ETC) tokom cooking procesa. Source format utice samo na kvalitet ulaznih podataka.

Zato je preporuka: importujte u lossless formatu (PNG, TGA) da biste sacuvali maksimalan kvalitet. Engine ce sam odluciti o finalnoj kompresiji.

Import podesavanja za teksture

Kada importujete teksturu, UE5 automatski detektuje neke parametre, ali mnoge morate rucno podesiti. Evo kriticnih:

Compression Settings:

Ovo je najvaznije podesavanje za teksture. Pogresna kompresija moze da duplira ili utrostruci memorijski otisak, ili unese nepotrebne artefakte.

Compression Setting GPU Format (PC) Velicina po pikselu Za sta se koristi
Default (DXT1/BC1) BC1 4 bita Base color bez alpha kanala
Default with Alpha (DXT5/BC3) BC3 8 bita Base color sa alpha kanalom
Normalmap (BC5) BC5 8 bita Normal mape -- cuva samo RG kanale
Masks (no sRGB) BC4 (grayscale) ili BC1 4 bita Roughness, metalness, AO, maske
HDR (BC6H) BC6H 8 bita HDR teksture, cubemap-ovi
Alpha (BC4) BC4 4 bita Single-channel teksture (height, opacity)
Grayscale G8 8 bita Nekompresovane grayscale teksture
Vector Displacement (RGBA8) RGBA8 32 bita Nekompresovane -- koristite samo kad morate

Detaljno o kompresiji govoricemo u sekciji 37.5.

sRGB:

Pogresno sRGB podesavanje je jedna od najcescih gresaka pocetnika. Normal mapa sa ukljucenim sRGB-om ce izgledati potpuno pogresno.

Maximum Texture Size: Omogucava vam da ogranicite maksimalnu rezoluciju teksture. Na primer, mozete importovati 4096x4096 teksturu ali da podesete max size na 2048 -- engine ce koristiti downscale verziju.

Tekstura Preporucena max velicina
Hero props (oruzje igraca, blizak pregled) 4096x4096
Standardni props 2048x2048
Udaljeni objekti, dekoracije 1024x1024
Sitni detalji 512x512 ili manje
UI elementi Po potrebi

LOD Bias: Ovo podesavanje pomera koji mip nivo se koristi. LOD Bias od 1 znaci da ce engine koristiti jedan mip nivo nize (manju rezoluciju) nego sto bi inace. Ovo je brz nacin da smanjite VRAM potrosnju bez reimporta.

LOD Group: Grupise teksture zajedno za LOD svrhe -- na primer, sve teksture materijala jednog mesh-a mogu da budu u istoj LOD grupi i da menjaju rezoluciju zajedno.

37.1.3 Import Podesavanja koja Uticu na Performans

Hajde da sumiramo najkritinija import podesavanja sa performansne strane -- ona koja, ako su pogresna, odmah stvaraju probleme:

Za mesh-eve:

  1. Build Nanite -- za high-poly mesh-eve, ovo je obavezno ako mesh ispunjava uslove (vidi poglavlje 30). Bez Nanite-a, high-poly mesh se renderuje u punoj kompleksnosti na svim distancama.

  2. Generate Lightmap UVs -- ako koristite baked osvetljenje (Lightmass), morate imati lightmap UV-ove. Podesavanje Min Lightmap Resolution i Source Lightmap Index direktno utice na kvalitet i velicinu lightmap-e.

  3. Auto Generate Collision -- automatska kolizija moze da bude previse detaljna. Za vecinu objekata, bolje je rucno napraviti jednostavne kolizione oblike (box, sphere, capsule) nego dozvoliti engine-u da generise convex hull sa hiljadama verteksa.

  4. LOD Auto Generation -- mozete odmah pri importu zatraziti automatsku generaciju LOD-ova. Ovo cemo detaljno pokriti u sekciji 37.2.

  5. Vertex Count -- Engine tokom importa prijavljuje koliko verteksa ima mesh. Koristite ovo kao red flag -- ako props ima vise od 100K verteksa, razmislite da li je to zaista potrebno.

Za teksture:

  1. Compression Setting -- pogresna kompresija = dvostruko ili cetvorostruko koriscenje VRAM-a. Detaljno u sekciji 37.5.

  2. sRGB -- pogresno = vizuelno pogresna tekstura. Normal mape, roughness, metalness, AO moraju imati iskljucen sRGB.

  3. Max Texture Size -- ne pustajte 4K teksture za objekte koji to ne zasluzuju. Postavite limit.

  4. Power of Two -- teksture bi trebalo da budu power-of-two dimenzija (256, 512, 1024, 2048, 4096). Non-POT teksture ne mogu da koriste mip-mape efikasno i mogu imati probleme sa kompresijom (detaljno u poglavlju 05).

  5. Mip-mape -- onemogucavanje mip-mapa za 3D teksture je skoro uvek greska. Mip-mape su neophodne za efikasno renderovanje udaljenih objekata. Jedini izuzetak su UI teksture i neke lookup table teksture.

37.1.4 Ceste Import Greske

Evo najcescih gresaka koje vidimo u praksi, sa objasnjenjima zasto su problematicne:

Greska 1: Import mesh-a bez cistog modela

Problem: Model iz ZBrush-a sa 8 miliona trouglova importovan direktno u UE5
         za objekat koji je stub u pozadini scene.

Posledica: 
- Vertex buffer zauzima stotine MB VRAM-a
- Rendering procesira milione nepotrebnih trouglova
- Bez LOD-ova, mesh se renderuje u punom detalju cak i na distanci od 500 metara

Resenje:
- Retopologizirajte mesh u DCC alatu (5,000-20,000 trouglova za tipican prop)
- Bake-ujte detalje u normal mapu
- Ili: ukljucite Nanite pri importu (za staticke mesh-eve)

Greska 2: Pogresna kompresija teksture

Problem: Normal mapa importovana sa "Default (DXT1/BC1)" umesto "Normalmap (BC5)"

Posledica:
- DXT1 kompresija uvodi blok artefakte koji su posebno vidljivi na normal mapama
- Osvetljenje na povrsini izgleda "lomljeno" i neprecizno
- Zapravo koristi MANJE memorije nego BC5, ali kvalitet je neprihvatljiv

Resenje:
- Uvek koristite Normalmap kompresiju za normal mape
- UE5 to obicno detektuje automatski ako je tekstura nazvana pravilno (*_N, *_Normal)

Greska 3: Nedostajuci second UV set za lightmap

Problem: Mesh importovan bez lightmap UV kanala, koristite baked osvetljenje

Posledica:
- Engine koristi UV0 (texture UV) za lightmap, sto uzrokuje overlapping
- Lightmap ima artefakte -- svetlost se "razliva" sa jednog dela mesh-a na drugi
- Build warnings za "Overlapping UVs"

Resenje:
- Ukljucite "Generate Lightmap UVs" pri importu
- Ili: napravite rucni lightmap UV set u DCC alatu (bolji kvalitet)

Greska 4: Pogresna skala pri importu

Problem: Model napravljen u Maya-i (default: centimetri) importovan u UE5 
         bez konverzije, ali umetnik je radio u incima

Posledica:
- Objekat je 2.54x veci ili manji nego sto treba
- Fizika ne radi kako se ocekuje (objekti "plutaju" ili propadaju)
- LOD distancije su pogresne (prelazu prerano ili prekasno)
- Lightmap rezolucija ne odgovara velicini objekta

Resenje:
- Proverite scale ODMAH pri importu
- UE5 koristi centimetre kao osnovu: 1 UE5 unit = 1 cm
- Dogovorite standard sa umetnickim timom unapred

Greska 5: Import animacija sa prekomernim brojem kljuceva

Problem: Animacija exportovana na 120 FPS bez "Remove Redundant Keys"

Posledica:
- Animacioni asset zauzima 4-10x vise memorije nego sto je potrebno
- Ovo se ne vidi lako jer su animacioni fajlovi "nevidljiv" trosak memorije
- Mnozite sa brojem animacija u projektu (stotine ili hiljade) -- memorija eksplodira

Resenje:
- Exportujte na 30 FPS za vecinu animacija (60 FPS za brze, precizne pokrete)
- Uvek ukljucite Remove Redundant Keys
- Koristite Animation Compression u UE5 (automatski, ali proverite podesavanja)

Greska 6: Importovanje duplikata

Problem: Isti mesh importovan vise puta sa razlicitim imenima

Posledica:
- Engine tretira svaki import kao zasebni asset
- Svaki zauzima posebnu memoriju na disku i u VRAM-u
- Nema instancing optimizacije -- GPU renderuje "razlicite" mesh-eve

Resenje:
- Koristite Reference Viewer da pronadjete duplikate
- Uspostavite jasnu naming konvenciju i folder strukturu
- Koristite Source Control (Perforce, Git LFS) za pracenje asset izvora

37.2 LOD Generacija

LOD (Level of Detail) je fundamentalni koncept optimizacije u real-time grafici. Ideja je jednostavna: objekti koji su daleko od kamere ne trebaju isti nivo detalja kao objekti blizu. Zasto trositi 50,000 trouglova na renderovanje objekta koji zauzima 20 piksela na ekranu?

LOD sistemi su detaljno obradjeni u poglavlju 45 (LOD optimizacija) u kontekstu runtime ponasanja. Ovde cemo se fokusirati na generaciju LOD-ova -- kako ih napraviti, automatski ili rucno, i koje opcije UE5 nudi.

37.2.1 Automatska LOD Generacija u UE5

UE5 ima ugradjenu funkcionalnost za automatsku generaciju LOD-ova. Mozete je aktivirati:

  1. Pri importu -- u Import Options postoji opcija za automatsko generisanje LOD-ova
  2. Naknadno -- otvorite Static Mesh Editor, u LOD Settings sekciji kliknite "Auto Generate LODs"
  3. Bulk edit -- mozete selektovati vise mesh-eva u Content Browser-u i generisati LOD-ove za sve odjednom

Kako auto-generacija radi

Kada zahtevate automatsku LOD generaciju, UE5 interno izvrsava sledece korake:

LOD0 (originalni mesh, npr. 50,000 trouglova)
  │
  ├── Mesh Analysis
  │   ├── Identifikacija UV seam-ova
  │   ├── Identifikacija material boundary-a
  │   ├── Identifikacija hard edge-ova
  │   └── Topoloska analiza
  │
  ├── Redukcija za LOD1 (npr. 50% = 25,000 trouglova)
  │   ├── Edge collapse operacije
  │   ├── Quadric Error Metric minimizacija
  │   └── Boundary preservation
  │
  ├── Redukcija za LOD2 (npr. 25% = 12,500 trouglova)
  │
  ├── Redukcija za LOD3 (npr. 12% = 6,000 trouglova)
  │
  └── Redukcija za LOD4 (npr. 5% = 2,500 trouglova)

LOD Group Settings

U Static Mesh Editor-u, svaki LOD nivo ima zasebna podesavanja:

Screen Size: Ovo je najvaznije podesavanje -- definise na kom procentu ekrana mesh prelazi na nizi LOD. Izrazava se kao procenat vertikalne rezolucije ekrana koji mesh zauzima.

LOD nivo Tipican Screen Size Znacenje
LOD0 1.0 Prikazuje se kada mesh zauzima >50% ekrana (ili default -- uvek prvi)
LOD1 0.5 Prelazi na LOD1 kada mesh zauzima manje od 50% ekrana
LOD2 0.25 Prelazi na LOD2 kada mesh zauzima manje od 25% ekrana
LOD3 0.12 Prelazi na LOD3 kada mesh zauzima manje od 12% ekrana
LOD4 0.06 Prelazi na LOD4 kada mesh zauzima manje od 6% ekrana

Napomena: Ove vrednosti su podrazumevane i trebalo bi ih podesiti za svaki mesh individualno na osnovu toga koliko je vizuelno vazan i koliko je LOD tranzicija primetna.

Reduction Settings po LOD nivou:

Za svaki LOD mozete podesiti:

LOD1 Reduction Settings:
├── Percent Triangles: 0.5        (50% od LOD0)
├── Percent Vertices: 0.5         (50% od LOD0)
├── Max Deviation: 0.0            (maksimalna dozvoljena devijacija od originala u UE jedinicama)
├── Silhouette: Important         (koliko je vazno sacuvati siluetu)
├── Texture: Important            (koliko je vazno sacuvati UV mapping)
├── Shading: Important            (koliko je vazno sacuvati normalne i shading)
├── Skinning: Off                 (za skeletal mesh: koliko je vazno sacuvati skin weights)
├── Welding Threshold: 0.0        (rastojanje ispod kog se verteksi spajaju)
└── Hard Edge Angle: 80.0         (ugao iznad kog se cuva hard edge)

Vazan detalj: Opcije Silhouette, Texture, i Shading imaju cetiri nivoa: Off, Lowest, Low, Normal, Important, Highest. Visi nivoi proizvode bolje izgledajuce LOD-ove ali sa vise trouglova (manje agresivna redukcija).

Prakticni primer: Auto-generacija LOD-ova za asset

Scenario: Importujete metalnu ogradu sa 15,000 trouglova.

Korak 1: Otvorite Static Mesh Editor
Korak 2: U LOD Settings, kliknite "Number of LODs" --> postavite na 4
Korak 3: Kliknite "Apply Changes"

Rezultat:
LOD0: 15,000 trouglova (original)           Screen Size: 1.0
LOD1:  7,500 trouglova (50% redukcija)      Screen Size: 0.5
LOD2:  3,750 trouglova (75% redukcija)      Screen Size: 0.25
LOD3:  1,500 trouglova (90% redukcija)      Screen Size: 0.12

Provera kvaliteta:
- Prebacite se na svaki LOD u editoru i vizuelno procenite
- LOD0-1: Treba da budu vizuelno identicni blizu
- LOD2: Manje odstupanje prihvatljivo na distanci
- LOD3: Silueta mora da bude prepoznatljiva, detalji mogu da se izgube

37.2.2 Mesh Reduction Algoritmi

Iza automatske LOD generacije stoje matematicki algoritmi za redukciju mesh-eva. Razumevanje ovih algoritama pomaze da znate zasto automatska redukcija nekada daje odlicne, a nekada lose rezultate.

Edge Collapse

Edge collapse je najcesci algoritam za mesh redukciju. Princip je jednostavan:

  1. Odaberite ivicu (edge) u mesh-u
  2. Spojite dva verteksa te ivice u jedan vertex
  3. Uklonite degenerisane trouglove (koji su imali oba verteksa te ivice)
Pre edge collapse:           Posle edge collapse:

    A                              A
   / \                            / \
  /   \                          /   \
 B-----C                        B-----C
  \   /                          \   /
   \ /                            \ /
    D                              D
     \                              
      E         -->        (E i D spojeni u D)
      
Rezultat: 2 trougla manje, 1 vertex manje, 1 edge manje

Pitanje je: koju ivicu kolapsirati? Tu dolazi prioritetni red -- svaka ivica dobija "cenu" kolapsa na osnovu toga koliko bi kolaps promenio izgled mesh-a. Ivice sa najmanjom cenom se kolapsiraju prve.

Quadric Error Metric (QEM)

Quadric Error Metric, razvijen od strane Garlanda i Heckberta (1997), je zlatni standard za racunanje cene kolapsa ivice. UE5-ov mesh reduction sistem koristi varijantu ovog algoritma.

Ideja:

  1. Za svaki vertex, kreirajte matricu (quadric) koja predstavlja sve ravni (planes) trouglova koji dodiruju taj vertex
  2. Cena pomeranja verteksa u novu poziciju je rastojanje od svih tih ravni, mereno ovom matricom
  3. Kada kolabrate ivicu (A,B) u novi vertex C, cena je QEM_A(C) + QEM_B(C)
  4. Pozicija novog verteksa C se bira tako da minimizuje ovu cenu
Matematicki:
Q = Σ Kp    (za svaku ravan p koja dodiruje vertex)

gde je Kp = p * pT (spoljanji proizvod vektora ravni)

Cena kolapsa ivice (v1, v2) u novi vertex v:
cost = vT * (Q1 + Q2) * v

Optimalna pozicija novog verteksa:
v_optimal = -(Q1 + Q2)^(-1) * [q14, q24, q34]T

Zasto je ovo dobro? Zato sto quadric metrika prirodno cuva:

Ogranicenja automatskih algoritama

Automatski algoritmi donose odluke samo na osnovu geometrije. Ne razumeju semantiku vase scene:

Problematicni slucajevi za auto-redukciju:

1. Tanke strukture (ograde, zice, antene)
   - Algoritam moze da "kolapsira" tanku strukturu u nistavilo
   - Ograda od 1000 trouglova moze postati neprepoznatljiva na LOD2

2. Rupe i prozori
   - Algoritam ne zna da je rupa namerna
   - Moze da "zatvori" prozore ili rupe na niskim LOD-ovima

3. Simetricni objekti
   - Algoritam ne cuva simetriju
   - Mesh koji je perfektno simetrican na LOD0 moze postati asimetrican na LOD2

4. Tekst i logotipi na mesh-u
   - Geometrijski tekst (extruded text) je prvi kandidat za redukciju
   - Na LOD1 tekst postaje necitljiv

5. Mesh sa mnogo disconnected components
   - Mali delovi mesh-a (srafovi, dugmici) nestaju na nizim LOD-ovima

37.2.3 Kvalitet vs Broj Trouglova po LOD Nivou

Koliko agresivno treba redukovati za svaki LOD nivo? Evo smernica na osnovu industrijskog iskustva:

Za tipicne props (namera, stupovi, kontejneri, nameštaj):

LOD nivo % od LOD0 Vizuelni kvalitet Tipicna distanca
LOD0 100% Pun detalj 0-10m
LOD1 40-60% Skoro identican 10-25m
LOD2 20-30% Male razlike primetne pri pazljivom gledanju 25-50m
LOD3 8-15% Silueta sacuvana, detalji izgubljeni 50-100m
LOD4 3-5% Samo prepoznatljiv oblik 100m+

Za vegetaciju (drvece, grmlje):

LOD nivo % od LOD0 Napomena
LOD0 100% Puno drvece sa svim listovima
LOD1 30-50% Smanjen broj grana i listova
LOD2 10-20% Pojednostavljena kruna drveta
LOD3 2-5% Billboard ili veoma prost mesh

Za arhitekturu (zgrade, mostovi):

LOD nivo % od LOD0 Napomena
LOD0 100% Pun detalj sa svim ukrasima
LOD1 50-70% Uklonjeni sitni detalji (oloci, srafovi)
LOD2 25-40% Pojednostavljen oblik, manje faceta
LOD3 10-20% Osnovni oblik zgrade

Kljucna formula:

Ocekivani pikselski otisak na ekranu = (mesh_size_world / distance_to_camera) * screen_resolution

Ako mesh na LOD3 distanci zauzima samo 400 piksela na ekranu,
a LOD3 ima 2000 trouglova, to je ~5 trouglova po pikselu.
To je vise nego dovoljno -- mogli biste da idete na 500 trouglova.

Pravilo palca: Na datoj distanci, mesh ne treba vise od 
~0.5-1 trougao po pikselu koji zauzima na ekranu.

37.2.4 Automatska vs Rucna LOD Generacija

Kada je automatska generacija dovoljno dobra, a kada morate praviti LOD-ove rucno?

Automatska generacija je dobra za:

Rucni LOD-ovi su potrebni za:

Hibridni pristup (preporucen za vecinu projekata):

1. Generisite automatske LOD-ove za SVE mesh-eve
2. Pregledajte LOD-ove za kriticne asset-e
3. Zamenite automatske LOD-ove rucnim gde je kvalitet nezadovoljavajuci
4. Koristite Nanite za high-poly staticne mesh-eve (eliminisite LOD problem potpuno)

37.3 Mesh Reduction (Decimacija)

Mesh reduction ili decimacija je proces smanjivanja broja poligona u mesh-u uz ocuvanje vizuelnog kvaliteta. Dok je LOD generacija specijalan slucaj (automatsko kreiranje vise nivoa detalja), mesh reduction je siri koncept koji ukljucuje i pripremu mesh-a pre importa u engine.

37.3.1 Decimation Algoritmi

Pored edge collapse-a i QEM-a (objasnjenih u 37.2.2), postoji nekoliko dodatnih pristupa:

Vertex Clustering

Najbrzi ali najgrublji algoritam. Princip:

  1. Podelite prostor na uniformnu mrezu (grid) celija
  2. Svi verteksi unutar jedne celije se spajaju u jedan vertex
  3. Trouglovi ciji su svi verteksi u istoj celiji se uklanjaju
[Originalni mesh u gridu]         [Posle clustering-a]

  *---*---*---*                    *-------*-------*
  |  /|  /|  /|                    |      /|      /|
  | / | / | / |                    |     / |     / |
  |/  |/  |/  |                    |    /  |    /  |
  *---*---*---*        -->         |   /   |   /   |
  |  /|  /|  /|                    |  /    |  /    |
  | / | / | / |                    | /     | /     |
  |/  |/  |/  |                    |/      |/      |
  *---*---*---*                    *-------*-------*

Prednosti: Veoma brz, predvidiv rezultat
Mane: Nizak kvalitet, ne cuva detalje, ne cuva oblik

Vertex clustering se retko koristi za finalne LOD-ove, ali je koristan za brze aproksimacije i debugging.

Vertex Removal

Umesto kolapsa ivica, ovaj pristup:

  1. Proceni "vaznost" svakog verteksa
  2. Ukloni najmanje vazne vertekse
  3. Retriangulise rupu

Manje kontrole nad rezultatom nego edge collapse, ali ponekad bolji za mesh-eve sa veoma neuniformnom topologijom.

Progressive Mesh

Tehnika koju je razvio Hugues Hoppe (1996):

  1. Izvrsite edge collapse operacije od najjeftinijeg ka najskupljem
  2. Snimite svaku operaciju u niz
  3. Rezultat je niz nivoa detalja koji se moze "premotati" u bilo kom pravcu
Full mesh (N trouglova)
    |  edge collapse 1
    v
   N-2 trouglova
    |  edge collapse 2
    v
   N-4 trouglova
    |  edge collapse 3
    v
   N-6 trouglova
    |  ...
    v
  Minimal mesh (M trouglova)

Prednost: Kontinuirani LOD, mozete se zaustaviti na bilo kom broju trouglova
Mana: Velik overhead po verteksu za cuvanje progressive mesh podataka

Nanite koristi slican princip na nivou klastera (vidi poglavlje 30).

37.3.2 Ocuvanje Kriticnih Osobina Mesh-a

Prost "smanji trouglove" pristup cesto daje lose rezultate jer ne uzima u obzir semanticke osobine mesh-a. Evo sta treba ocuvati:

UV Seam Preservation

UV seam je linija gde se UV mapping "sece". Ako algoritam kolapsa ivicu koja je na UV seam-u, moze da poremeti ceo UV mapping:

Pre kolapsa (UV prostor):        Posle kolapsa (UV prostor):

  +-------+  +-------+            +-------+  +-------+
  |       |  |       |            |       |  |      /|
  |  UV   |  |  UV   |            |  UV   |  |    /  |
  |  A    |  |  B    |            |  A    |  |  /  B |
  |       |  |       |            |       |  |/      |
  +---*---+  +---*---+     -->    +---*---+--*-------+
      ^          ^                    ^      ^
      |          |                    |      |
   Isti vertex sa         Kolaps spojio seam vertekse --
   razlicitim UV-ovima    tekstura je sada razmazana!

UE5-ov mesh reducer ima opciju za UV seam preservation -- podesavanje "Texture: Important" u LOD settings-u povecava cenu kolapsa ivica na UV seam-ovima.

Material Boundary Preservation

Ako mesh ima vise materijala (material slots), granica izmedju materijala mora da se sacuva. Kolaps ivice na granici materijala bi spojio dva razlicita materijala:

Pre kolapsa:                Posle kolapsa (greska):
+--------+--------+         +--------+--------+
|        |        |         |       /          |
| Mat A  | Mat B  |         | Mat A/   Mat B   |
|        |        |   -->   |    /             |
+--------+--------+         +--/------+--------+
                              ^
                              |
                       Granica materijala
                       je narusena!

Podesavanje "Shading: Important" u UE5 cuva material boundary-e.

Silhouette Preservation

Silueta mesh-a (obris kada se gleda sa strane) je ono sto ljudski mozak najlakse prepoznaje. Cak i na niskim LOD nivoima, silueta mora da bude prepoznatljiva:

LOD0 silueta:    LOD3 silueta (dobra):    LOD3 silueta (losa):

    /\                /\                      /\
   /  \              /  \                    |  |
  /    \            /    \                   |  |
 |      |          |      |                  |  |
 | okna |          |      |                  |  |
 |      |          |      |                  |  |
 +------+          +------+                  +--+

 Zgrada sa         Manje detalja           Potpuno drugaciji
 detaljima         ali prepoznatljivo      oblik -- neprihvatljivo

Podesavanje "Silhouette: Important" povecava cenu kolapsa ivica na konturama mesh-a (ivice gde je ugao izmedju normala susednih trouglova najveci).

Hard Edge Preservation

Hard edges (ivice gde se normalne ne glatko interpoliraju) definisu vizuelno "ostrine" objekta. Kolaps hard edge-a menja shading objekta:

Hard Edge Angle podesavanje u UE5:
- Ako je ugao izmedju normala susednih trouglova > Hard Edge Angle,
  ta ivica se cuva (ne kolapsira se)
- Default: 80 stepeni
- Za mesh-eve sa mnogo ostrih ivica (masinerija, robotika): smanjite na 45-60
- Za organske mesh-eve (kamenje, vegetacija): ostavite default ili povecajte

37.3.3 Agresivna vs Konzervativna Redukcija

Koliko agresivno treba redukovati mesh zavisi od konteksta:

Konzervativna redukcija (20-40% smanjenje):

Kada koristiti:
- Hero props (oruzje, oklop igraca)
- Objekti koji su cesto blizu kamere
- Objekti sa tankim/linearnim strukturama
- Objekti sa slozenim UV mapping-om (detaljne teksture)
- Likovi u cutscenama

Podesavanja:
- Silhouette: Highest
- Texture: Highest
- Shading: Important
- Welding Threshold: 0.0 (bez welding-a)

Agresivna redukcija (60-90% smanjenje):

Kada koristiti:
- Pozadinski objekti (udaljene zgrade, planine)
- LOD3/LOD4 nivoi za sve osim hero asset-a
- Mesh-evi sa organskim oblicima koji tolerisu simplifikaciju
- Proxy mesh-evi za HLOD (Hierarchical LOD)

Podesavanja:
- Silhouette: Normal ili Low
- Texture: Normal ili Low
- Shading: Normal ili Low
- Welding Threshold: 1.0-5.0 (agresivan welding blizih verteksa)

Primer iz prakse:

Asset: Industrijska masina, LOD0 = 45,000 trouglova

Konzervativna redukcija:
LOD1: 27,000 trouglova (40% redukcija) -- svi kljucni detalji sacuvani
LOD2: 15,000 trouglova (67% redukcija) -- sitni srafovi i zice uklonjeni
LOD3:  5,000 trouglova (89% redukcija) -- samo glavna forma

Agresivna redukcija:
LOD1: 15,000 trouglova (67% redukcija) -- neke detalje vec gubimo
LOD2:  5,000 trouglova (89% redukcija) -- samo gruba forma
LOD3:  1,000 trouglova (98% redukcija) -- jedva prepoznatljiv oblik

Za pozadinsku masinu u fabrici: agresivna redukcija je sasvim OK
Za masinu sa kojom igrac interaguje: konzervativna je obavezna

37.3.4 Alati za Mesh Redukciju

UE5 Built-in Mesh Reduction

UE5 dolazi sa ugradjenim mesh reduction sistemom koji se koristi za automatsku LOD generaciju. Prednosti:

Mane:

Simplygon

Simplygon (Microsoft) je industrijski standard za mesh optimization. Ranije se licencirao zasebno, ali je Microsoft ucinio Simplygon besplatnim za UE5 korisnike putem Simplygon UE5 plugina.

Prednosti:

Mane:

Primer Simplygon podesavanja u UE5:

// Simplygon LOD Recipe (primer za prop)
Reduction Processor:
  Triangle Ratio: 0.5          // 50% trouglova
  Feature Importance:
    Texture:    1.5             // Visi prioritet UV ocuvanja
    Shading:    1.0             // Normalan prioritet za shading
    Silhouette: 2.0             // Najvisi prioritet za siluetu
    Skinning:   0.5             // Nizak prioritet za skin weights
  
Material Baking (opciono):
  Output Resolution: 1024x1024 // Bake sve materijale u jedan atlas
  Channels: [BaseColor, Normal, ORM]

InstaLOD

InstaLOD je jos jedan profesionalni alat za mesh optimization:

DCC alati (Blender, Maya)

Mesh redukciju mozete raditi i u DCC alatima pre importa:

Blender:

Maya:

ZBrush:

Prednost rada u DCC alatu: imace potpunu kontrolu nad rezultatom i mozete rucno popraviti probleme pre importa.


37.4 Detaljni Pregled Mesh Redukcije u Praksi

37.4.1 Workflow od High-Poly do Game-Ready

Tipiocni workflow za pripremu mesh-a za igru izgleda ovako:

Korak 1: High-Poly Model (DCC alat)
         ZBrush: 10,000,000 trouglova
         Pun skulpturski detalj
         |
         v
Korak 2: Retopologija (DCC alat)
         Blender/Maya: 15,000 trouglova
         Cista topologija, proper UV-ovi
         |
         v
Korak 3: Baking (DCC alat ili Substance)
         Normal mapa: high-poly detalji na low-poly mesh-u
         AO mapa, Height mapa, Curvature mapa
         |
         v
Korak 4: Texturing (Substance Painter/Designer)
         Base Color, Roughness, Metalness, Emissive
         |
         v
Korak 5: Export FBX
         Game-ready mesh sa svim teksturama
         |
         v
Korak 6: Import u UE5
         Podesavanje import settings
         LOD generacija (automatska ili import rucnih LOD-ova)
         Materijal setup
         Collision setup
         |
         v
Korak 7: Validacija
         Provera triangle count-a, texture size-a, LOD tranzicija
         Performansno testiranje u sceni

37.4.2 Koliko Trouglova je "Previse"?

Ovo pitanje nema univerzalan odgovor -- zavisi od platforme, tipa igre, broja objekata na ekranu, i komplesnosti renderinga. Ali evo smernica:

Budzeti po tipu objekta (PC, moderan hardware):

Tip objekta LOD0 trouglova Napomena
Glavni igrac (third person) 50,000-150,000 Najblizi kameri, najvise detalja
NPC (vazni) 30,000-80,000 Vidljivi u dijalogu i cutscenama
NPC (pozadinski) 5,000-20,000 Retko blizu kamere
Oruzje (first person) 10,000-30,000 Veoma blizu kamere, detalji bitni
Vozilo 30,000-100,000 Zavisno od igre
Zgrada (cela) 20,000-80,000 Spoljasnjost
Prop (veliki) 5,000-20,000 Namestaj, masine
Prop (mali) 500-5,000 Flaše, kutije, alati
Vegetacija (drvo) 10,000-50,000 LOD0, sa listovima
Vegetacija (trava) 10-100 po instanci Hiljade instanci!

Za mobilne platforme, podelite sve sa 3-5x.

Napomena o Nanite-u: Ako koristite Nanite (poglavlje 30), ovi budzeti se ne primenjuju za LOD0 -- Nanite automatski upravlja kompleksnoscu. Ali LOD-ovi za ne-Nanite fallback i dalje trebaju da postoje.


37.5 Texture Compression Settings

Teksture su tipicno najveci potrosac VRAM-a u igri. Pravilna kompresija moze da smanji memorijski otisak za 4-8x bez primetnog gubitka kvaliteta. Pogresna kompresija moze da ili unisti kvalitet ili bespotrebno trosi memoriju.

O teksturama i mip-mapama detaljno smo govorili u poglavlju 05. Ovde cemo se fokusirati na prakticna podesavanja kompresije u UE5 i kako doneti ispravne odluke.

37.5.1 GPU Texture Compression -- Kako Radi

GPU ne koristi PNG, JPEG ili TGA u runtime-u. Teksture se kompresuju u specijalne formate koje GPU hardver moze da dekompresuje u realnom vremenu, bez performansnog troska. Ovi formati rade na principu blok kompresije -- tekstura se deli na blokove od 4x4 piksela, i svaki blok se kompresuje nezavisno.

Tekstura 1024x1024:
- Nekompresovana RGBA8: 1024 * 1024 * 4 bajta = 4 MB
- BC1 kompresovana:     1024 * 1024 * 0.5 bajta = 0.5 MB (8x manja!)
- BC3 kompresovana:     1024 * 1024 * 1 bajt = 1 MB (4x manja)
- BC7 kompresovana:     1024 * 1024 * 1 bajt = 1 MB (4x manja, bolji kvalitet)

Sa mip-mapama (dodatnih ~33%):
- Nekompresovana RGBA8: ~5.33 MB
- BC1: ~0.67 MB
- BC3: ~1.33 MB

37.5.2 Izbor Formata Kompresije po Tipu Teksture

Ovo je najvaznija tabela u ovom poglavlju. Odštampajte je i zalepite pored monitora:

PC (DirectX -- BC formati)

Tip teksture UE5 Compression Setting GPU Format Bitova/piksel Napomene
Base Color (bez alpha) Default (DXT1/BC1) BC1 4 Standardna kompresija, dobar kvalitet za boje
Base Color (sa alpha) Default with Alpha (DXT5/BC3) BC3 8 BC1 za boju + BC4 za alpha
Normal Map Normalmap (BC5) BC5 8 Cuva samo RG kanale, Z se racuna u shaderu
Roughness/Metalness/AO (pakovane) Masks (no sRGB) BC1 4 Pakujte R/M/AO u RGB kanale jedne teksture
Single channel (height, opacity) Alpha (BC4) BC4 4 Samo jedan kanal, visoka preciznost
HDR (environment mape) HDR (BC6H) BC6H 8 Podrzava negativne vrednosti i HDR opseg
Visok kvalitet boja (UI, cutscene) BC7 BC7 8 Najvisi kvalitet blok kompresije
Distance Field Font DistanceFieldFont G8 8 Za SDF tekst rendering
Lookup Table (LUT) UserInterface2D (RGBA) RGBA8 32 Nekompresovano, za podatke gde je preciznost kriticna

Mobilne platforme (ASTC i ETC)

Tip teksture Format Bitova/piksel Napomene
Base Color ASTC 4x4 8 Najvisi kvalitet ASTC
Base Color (ustedjiv) ASTC 6x6 3.56 Dobar balans kvaliteta i velicine
Base Color (agresivan) ASTC 8x8 2 Niski kvalitet, za pozadinske teksture
Normal Map ASTC 4x4 8 Koristite za normal mape
Maske ETC2 R11 4 Jednokanalne teksture
Legacy (stariji uredjaji) ETC2 4/8 Za kompatibilnost sa starijim uredjajima

ASTC prednosti nad ETC:

37.5.3 Maximum Texture Size -- Kada i Kako Smanjiti

Rezolucija teksture direktno utice na VRAM potrosnju. Evo tabele velicina:

Velicina teksture u VRAM-u (BC1, sa mip-mapama):

  256x256:    ~43 KB
  512x512:   ~171 KB
  1024x1024:  ~683 KB    (~0.67 MB)
  2048x2048: ~2.73 MB
  4096x4096: ~10.9 MB
  8192x8192: ~43.7 MB

Za BC3/BC5/BC7 (dvostruko):
  2048x2048: ~5.46 MB
  4096x4096: ~21.8 MB

Pomnozite ovo sa brojem tekstura u sceni. Tipican materijal ima 3-5 tekstura (Base Color, Normal, ORM/Packed, Emissive...). Ako imate 100 jedinstvenih materijala sa po 3 teksture na 4096x4096 u BC3:

100 materijala x 3 teksture x 21.8 MB = 6.54 GB VRAM samo za teksture!

To je previse za vecinu GPU-ova. Zato je pravilno dimenzionisanje tekstura kriticno.

Pravilo za odredjivanje rezolucije teksture:

Korak 1: Odredite najvecu velicinu objekta na ekranu (u pikselima)
Korak 2: Koliko UV prostora objekat koristi (0.0-1.0 opseg)
Korak 3: Potrebna rezolucija = screen_pixels / UV_coverage

Primer:
- Objekat zauzima maksimalno 500x500 piksela na ekranu
- UV coverage je 70% (tipicno za dobro UV-ovan objekat)
- Potrebna rezolucija: 500 / 0.7 = ~714 piksela
- Najbliza POT: 1024x1024

Dakle, za ovaj objekat, 1024x1024 je sasvim dovoljno.
Davanje 4096x4096 bi bilo bespotrebno trosenje 16x vise VRAM-a.

37.5.4 LOD Bias za Teksture

LOD Bias je podesavanje koje pomera koji mip nivo se koristi za teksturu. Ovo je razlicito od mesh LOD-a -- radi se o mip-mapama teksture, ne o geometriji.

LOD Bias = 0 (default):
  Engine koristi mip nivo koji najbolje odgovara piksel-texel odnosu

LOD Bias = 1:
  Engine koristi jedan mip nivo nize (manja rezolucija)
  Efektivno: 4096 tekstura se ponasa kao 2048

LOD Bias = 2:
  Dva mip nivoa nize
  Efektivno: 4096 tekstura se ponasa kao 1024

LOD Bias = -1:
  Jedan mip nivo vise (ostrija tekstura)
  Retko korisno, moze da uzrokuje aliasing

LOD Bias je korisno za:

U UE5, LOD Bias se moze podesiti:

  1. Per-texture -- u Texture Editor-u, "LOD Bias" podesavanje
  2. Per-texture group -- u Project Settings, "Texture LOD Groups"
  3. Globalno -- konzolna komanda r.Streaming.MipBias

37.5.5 Platform-Specific Compression

UE5 automatski konvertuje teksture u odgovarajuci format za ciljnu platformu tokom cooking procesa. Ali mozete kontrolisati ovaj proces:

Per-Platform Texture Override (u Texture Editor):

PC:
  Compression: BC1/BC3/BC5/BC7 (zavisno od tipa)
  Max Texture Size: 4096

PS5 / Xbox Series X:
  Compression: BC1/BC3/BC5/BC7
  Max Texture Size: 4096

Nintendo Switch:
  Compression: ASTC
  Max Texture Size: 1024-2048 (manji budzet)

Android:
  Compression: ASTC (moderni uredjaji) ili ETC2 (stariji)
  Max Texture Size: 1024-2048

iOS:
  Compression: ASTC
  Max Texture Size: 1024-2048

Mozete podesiti ove override-ove u Texture Editor-u klikom na "Per Platform" podesavanja. Ovo je kljucno za multi-platform projekte -- ne zelite da Switch pokusava da ucita 4096 teksture.

37.5.6 Pakovanje Tekstura (Channel Packing)

Jedna od najvaznijih tehnika za ustedu memorije je pakovanje vise tekstura u kanale jedne teksture. Umesto tri zasebne grayscale teksture (Roughness, Metalness, AO), pakujte ih u RGB kanale jedne teksture:

Bez pakovanja:                    Sa pakovanjem:
Roughness.png  (2048, BC4)  2.7MB    ORM.png (2048, BC1)  2.7MB
Metalness.png  (2048, BC4)  2.7MB    (R=AO, G=Roughness, B=Metalness)
AO.png         (2048, BC4)  2.7MB    
UKUPNO: 8.1 MB                      UKUPNO: 2.7 MB

Usteda: 5.4 MB po materijalu!
Sa 100 materijala: 540 MB ustedjevine!

UE5 koristi ovaj pristup u svom standardnom PBR workflow-u -- "ORM" tekstura pakuje Occlusion (R), Roughness (G), Metalness (B).

Pravila za channel packing:

  1. Pakujte samo podatke koji se uvek koriste zajedno (iste mip-mape, isti LOD)
  2. Svi pakovani kanali moraju imati istu rezoluciju
  3. Ne pakujte sRGB i linearne podatke zajedno (razlicit color space)
  4. Ne pakujte normal mapu sa drugim podacima -- normal mapa koristi posebnu kompresiju (BC5)
  5. Koristite "Masks (no sRGB)" kompresiju za pakovane teksture

37.6 Asset Audit

Cak i sa najboljim namerama, kroz vreme projekta se nakupljaju problematicni asset-i. Tekstura koje je neko importovao na 8192x8192 "samo da proveri nesto" i nikada je nije smanjio. Mesh bez LOD-ova koji je zavrisen u finalnoj sceni. Duplirani materijali koji zauzimaju memoriju bez razloga.

Asset audit je proces pregleda svih asset-a u projektu i identifikacija problema. UE5 nudi nekoliko alata za ovo.

37.6.1 Kako Pronaci Problematicne Asset-e

Statistics Window

Window > Statistics otvara prozor koji prikazuje statistiku svih asset-a u projektu:

Statistics Window prikazuje:
- Ukupan broj asset-a po tipu (Static Mesh, Texture, Material, itd.)
- Memorijski otisak po tipu
- Prosecne velicine
- Outlier-e (asset-i koji su znacajno veci od proseka)

Content Browser Filters

Content Browser ima napredne filtere za pronalazenje problematicnih asset-a:

Korisni filteri:
- Tip: Static Mesh --> Sort by Triangle Count (descending)
- Tip: Texture2D --> Sort by Size (descending)
- Tip: Texture2D, Filter: Max Dimension > 4096
- Tip: Static Mesh, Filter: LOD Count = 1 (mesh-evi bez LOD-ova)

Audit putem konzolnih komandi

UE5 ima konzolne komande (~ u editoru) za analizu:

// Lista svih tekstura vecih od odredjene velicine
ListTextures                    // Izlista sve ucitane teksture i njihovu velicinu

// Statistika memorije
Stat Memory                     // Prikazuje memorijski pregled
Stat TexturePool                // VRAM koriscenje za teksture
Stat Streaming                  // Status streaming sistema
Stat SceneRendering             // Rendering statistika ukljucujuci triangle count

// Mesh statistika
Stat StaticMesh                 // Statistika static mesh-eva

37.6.2 Size Map Tool

Size Map je vizuelni alat koji prikazuje velicinu asset-a i njihovih zavisnosti kao treemap vizualizaciju. Ovo je jedan od najkorisnijih alata za pronalazenje "debelih" asset-a.

Kako koristiti Size Map:
1. Desni klik na folder u Content Browser
2. "Size Map" (ili Asset Actions > Size Map)
3. Prikazuje se treemap gde je velicina svakog pravougaonika 
   proporcionalna velicini asset-a

Sta traziti:
- Ogromni pravougaonici su asset-i koji zauzimaju najvise prostora
- Cesto su to teksture (narucito nekompresovane ili prevelike)
- Ponekad su to mesh-evi sa previse geometrije
- Retko, ali moguce -- nepotrebno velike data tabele ili Blueprint-ovi

Size Map takodje prikazuje zavisnosti -- koliko prostora zauzima asset zajedno sa svim asset-ima od kojih zavisi (materijali, teksture, itd.).

37.6.3 Reference Viewer

Reference Viewer prikazuje graf zavisnosti izmedju asset-a. Kljucan je za razumevanje zasto je odredjeni asset ucitan u memoriju i sta zavisi od njega.

Kako koristiti Reference Viewer:
1. Desni klik na asset u Content Browser
2. "Reference Viewer"
3. Prikazuje se graf sa strelicama:
   - Strelice KA asset-u = asset-i koji ga referenciraju (zavisnici)
   - Strelice OD asset-a = asset-i od kojih on zavisi

Primer:
SM_Building --> MI_BuildingWall --> M_BuildingWall --> T_Wall_BaseColor
                                                  --> T_Wall_Normal
                                                  --> T_Wall_ORM

Ako izbrisete T_Wall_BaseColor, M_BuildingWall ce biti broken,
sto znaci da MI_BuildingWall nece raditi, sto znaci da SM_Building
nece imati materijal na jednoj povrsini.

Prakticna upotreba Reference Viewer-a:

  1. Pronalazenje nekoriscenih asset-a -- asset bez zavisnika (nista ga ne referencira) je potencijalno nekoristen
  2. Razumevanje memory chain-a -- ako jedan mali Blueprint ucitava ogromnu teksturu, Reference Viewer pokazuje taj lanac
  3. Analiza hard vs soft referenci -- hard referenca znaci automatsko ucitavanje, soft referenca ne (vidi poglavlje 36)
  4. Pronalazenje circular dependency-a -- asset-i koji medusobno referenciraju jedni druge

37.6.4 Asset Audit Alat u UE5

UE5 ima dedicirani Asset Audit prozor (Window > Developer Tools > Asset Audit) koji kombinuje vise analiza u jedan interfejs:

Asset Audit prikazuje kolone:
- Asset Name
- Asset Type
- Disk Size
- Memory Size (procenjena runtime velicina)
- Triangle Count (za mesh-eve)
- Texture Size (za teksture)
- LOD Count (za mesh-eve)
- Material Count
- Nanite Enabled (da/ne)
- Has Collision (da/ne)

Mozete sortirati po bilo kojoj koloni da brzo pronadjete probleme. Na primer:

37.6.5 Statistike i Budzeti

Uspostavljanje performansnih budzeta je kljuc za odrzavanje projekta zdravim. Budžet definise maksimalne dozvoljene vrednosti za razlicite kategorije asset-a:

Primer performansnog budzeta za PC igru (target: 60 FPS, GPU sa 8 GB VRAM):

VRAM Budzet:
├── Teksture:           3.5 GB (44%)
│   ├── World teksture: 2.0 GB
│   ├── Character:      0.5 GB
│   ├── Effects:        0.3 GB
│   ├── UI:             0.2 GB
│   └── Ostalo:         0.5 GB
├── Geometry (Vertex/Index Buffers): 1.5 GB (19%)
│   ├── Nanite streaming pool: 1.0 GB
│   └── Non-Nanite mesh-evi:   0.5 GB
├── Render Targets:     1.5 GB (19%)
│   ├── GBuffer:        ~0.3 GB (zavisno od rezolucije)
│   ├── Shadow Maps:    ~0.5 GB
│   └── Post-process:   ~0.7 GB
├── Shaders:            0.5 GB (6%)
└── Ostalo (buffers, queries): 1.0 GB (12%)

UKUPNO: 8.0 GB

Per-asset budzeti:

Mesh-evi:
- Pojedinacni mesh: max 100,000 trouglova na LOD0 (osim hero)
- Mesh bez LOD-ova: ZABRANJENO za mesh-eve sa >500 trouglova
- Mesh bez Nanite-a i bez LOD-ova: ZABRANJENO za mesh-eve sa >2000 trouglova

Teksture:
- Pojedinacna tekstura: max 4096x4096
- 8192x8192: samo uz eksplicitno odobrenje (environment panorame, sky)
- Nekompresovane teksture: ZABRANJENE (osim lookup tabela)
- Normal mape bez BC5/Normalmap kompresije: ZABRANJENE

Materijali:
- Max instruction count: 200 instrukcija za base pass (proverite u Material Stats)
- Max texture samples: 8 po materijalu (vise = vise bandwidth)

37.7 Kako Losi Asset-i Ubijaju Performans

Ova sekcija je "gallery of horrors" -- katalog nacina na koje asset-i mogu da uniste performans vase igre. Svaki od ovih problema sam video u produkcijskim projektima.

37.7.1 Prevelike Teksture Gutaju VRAM

Scenario: Tim koristi 4096x4096 teksture za SVE objekte, ukljucujuci
          male props kao sto su flaše, tanjiri, i kasike.

Problem:
- Flasa na stolu zauzima mozda 50x100 piksela na ekranu
- Ali njena tekstura zauzima 21.8 MB VRAM-a (4096, BC3, sa mip-mapama)
- Mip-mapping ce koristiti nize nivoe za male objekte, ali cela
  mip chain mora da bude u VRAM-u (ili streaming pool-u)
- 50 takvih props-a = 1 GB VRAM-a za objekte koji zauzimaju 5% ekrana

Posledice:
- VRAM overflow --> teksture se downgrejduju ili ne ucitavaju
- Streaming stutter --> engine stalno ucitava/izbacuje teksture
- Duga vremena ucitavanja --> vise podataka za streaming sa diska

Resenje:
- Koristite odgovarajucu rezoluciju za svaki objekat
- Flaša: 512x512 je vise nego dovoljno
- 512x512 BC3: ~0.34 MB umesto 21.8 MB = 64x usteda!

37.7.2 Previse Detaljni Mesh-evi gde Nisu Potrebni

Scenario: Svaki sraf na masini je modelovan sa 500 trouglova (cilindar, navoj).
          Masina ima 40 srafova. To je 20,000 trouglova samo za srafove.

Problem:
- Na distanci od 5 metara, sraf zauzima mozda 3 piksela na ekranu
- 500 trouglova za 3 piksela = 167 trouglova po pikselu (brutalno nefiksano)
- Te trouglove GPU mora da procesira kroz vertex shader, clip, rasterize...
- Mnogi trouglovi su sub-pixel (manji od jednog piksela) = potpuni otpad

Posledice:
- Visok triangle count bez vizuelne koristi
- Quad overdraw (GPU procesira 2x2 blokove piksela, sub-pixel trouglovi
  trose ceo quad za 0-1 korisnih piksela)
- Veci vertex buffer = vise VRAM-a

Resenje:
- Modelujte srafove kao deo mesh-a, bez individualnih cilindara
- Koristite normal mapu za detalje srafova
- Ili: koristite Nanite koji automatski resava sub-pixel trouglove

37.7.3 Nedostajuci LOD-ovi

Scenario: Drvo sa 30,000 trouglova nema LOD-ove. Scena ima 500 takvih drveca.

Problem:
- Na rastojanju od 200 metara, svako drvo zauzima mozda 50 piksela na ekranu
- Ali GPU i dalje renderuje svih 30,000 trouglova za svako drvo
- 500 drveca x 30,000 = 15,000,000 trouglova za drvece
- Od tih 15 miliona, mozda 14 miliona su potpuno nevidljivi (sub-pixel)

Posledice:
- GPU bottleneck na vertex processing
- Drasticno smanjen frame rate
- Occlusion culling ne pomaze jer su drveca cesto vidljiva (delimicno)

Resenje:
- Dodajte LOD-ove! LOD3 za drvece na 200m moze imati 500-1000 trouglova
- Sa LOD-ovima: 500 x 1,000 = 500,000 trouglova umesto 15,000,000
- To je 30x smanjenje, a vizuelno je identicno na toj distanci

37.7.4 Nekompresovane Teksture

Scenario: Umetnik je importovao teksturu kao "UserInterface2D (RGBA)"
          umesto "Default (DXT1/BC1)" jer "kvalitet je bolji".

Problem:
- RGBA8 (nekompresovano): 2048x2048 = 16 MB (sa mip-mapama: ~21 MB)
- BC1 (kompresovano): 2048x2048 = 2.7 MB (sa mip-mapama: ~3.5 MB)
- Razlika: 6x vise VRAM-a za jednu teksturu
- Za 50 tekstura: 1050 MB vs 175 MB

Posledice:
- Enormna VRAM potrosnja
- Sporiji texture streaming (vise podataka za ucitavanje)
- Na mobilnim uredjajima: crash zbog nedostatka memorije

Resenje:
- Koristite odgovarajucu kompresiju za svaki tip teksture (sekcija 37.5.2)
- BC1/BC7 za base color
- BC5 za normal mape
- BC4 za single-channel maske
- Nikada RGBA8 osim za lookup tabele gde je preciznost kriticna

37.7.5 Duplirani Asset-i

Scenario: Dva umetnika su importovala isti mesh za razlicite delove mape.
          "SM_Barrel_01" i "SM_Barrel_ForWarehouse" su isti FBX.

Problem:
- Engine tretira ovo kao dva razlicita mesh-a
- Svaki zauzima svoj prostor u VRAM-u (vertex buffer, index buffer)
- GPU ne moze da koristi instancing izmedju njih (razliciti mesh-evi!)
- Takve iste teksture i materijali duplirani

Posledice:
- 2x VRAM potrosnja za istu geometriju
- Nema instancing optimizacije
- Teze odrzavanje (promena na jednom ne utice na drugi)
- Veca velicina paketa igre

Resenje:
- Uspostavite striktnu naming konvenciju (sekcija 37.8.1)
- Koristite Reference Viewer za pronalazenje duplikata
- Koristite Asset Audit alat
- Implementirajte automatske provere u CI/CD pipeline-u

37.7.6 Nekorisceni Asset-i

Scenario: Projekat je u razvoju 2 godine. Mnogi asset-i su zamenjeni novijim
          verzijama, ali stari nisu obrisani.

Problem:
- Nekorisceni asset-i i dalje zauzimaju prostor na disku
- Tokom cooking-a (pakovanja igre), UE5 OBICNO ne ukljucuje nekoriscene
  asset-e, ALI ima izuzetaka:
  - Asset-i u "Always Cook" folderima
  - Asset-i koje referencira Data Table ili Blueprint koji se koristi
  - Asset-i u default map-i

Posledice:
- Veca velicina projekta na disku (usporava backup, source control)
- Potencijalno veci packaged build ako nisu pravilno iskljuceni
- Konfuzija u timu -- "da li se ovo koristi ili ne?"

Resenje:
- Redovno pokrecite "Find Unused Assets" analizu
- Koristite Reference Viewer za proveru referencija
- Premestite stare asset-e u "_Deprecated" folder pre brisanja
- Proverite size of cooked content pre i posle ciscenja

37.7.7 Zbirna Tabela Problema

Problem Symptom Alat za detekciju Resenje
Prevelike teksture Visoka VRAM potrosnja, stutter stat TexturePool, Size Map Smanjite rezoluciju, pravilna kompresija
Previse trouglova Nizak FPS, GPU bound stat SceneRendering LOD-ovi, Nanite, mesh redukcija
Nedostajuci LOD-ovi Isti triangle count na svim distancama Asset Audit (LOD Count = 1) Genersite LOD-ove
Nekompresovane teksture Ogroman VRAM stat TexturePool, Texture Editor Pravilna kompresija (BC1/BC3/BC5)
Duplikati Velik projekat, nema instancinga Reference Viewer, search Koristite originalni asset
Nekorisceni asset-i Velika velicina paketa Unused Asset scan Obrišite ili premestite
Pogresno sRGB Vizuelni artefakti Texture Editor pregled Ispravite sRGB podesavanje
Previse materijala na mesh-u Previse draw call-ova Static Mesh Editor Kombinujte materijale, atlas

37.8 Best Practices za Asset Pipeline

37.8.1 Naming Konvencije

Konzistentno imenovanje asset-a je temelj dobrog pipeline-a. Nema "jedne ispravne" konvencije, ali evo preporucene koja se koristi u mnogim studijima:

Prefix konvencija po tipu asset-a

SM_     Static Mesh              SM_Chair_01
SK_     Skeletal Mesh            SK_Character_Hero
T_      Texture                  T_Chair_BaseColor
M_      Material                 M_Wood_Dark
MI_     Material Instance        MI_Wood_Dark_Red
A_      Animation Sequence       A_Hero_Walk_Fwd
AB_     Animation Blueprint      AB_Hero
ABP_    Animation Blueprint      ABP_Hero (alternativna konvencija)
BP_     Blueprint                BP_Door_Interactive
WBP_    Widget Blueprint         WBP_HUD_HealthBar
S_      Sound (Cue/Wave)         S_Explosion_01
NS_     Niagara System           NS_Fire_Large
P_      Particle System          P_Smoke_01 (legacy Cascade)
PC_     Physics Constraint       PC_Ragdoll_Arm
PHYS_   Physics Asset            PHYS_Hero
SKEL_   Skeleton                 SKEL_Hero
MF_     Material Function        MF_WindAnimation
MT_     Material Texture         MT_Noise_Perlin

Suffix konvencija za teksture

_BC     Base Color               T_Chair_BC
_N      Normal Map               T_Chair_N
_ORM    Occlusion/Roughness/Metal T_Chair_ORM
_R      Roughness                T_Chair_R (ako nije pakovan)
_M      Metalness                T_Chair_M (ako nije pakovan)
_AO     Ambient Occlusion        T_Chair_AO (ako nije pakovan)
_E      Emissive                 T_Chair_E
_H      Height                   T_Chair_H
_O      Opacity                  T_Chair_O
_D      Displacement             T_Chair_D
_MSK    Mask (genericna)         T_Chair_MSK

Zasto je ovo vazno za pipeline?

  1. Automatska detekcija tipa -- UE5 moze da prepozna "_N" suffix i automatski podesi Normalmap kompresiju
  2. Batch operacije -- mozete selektovati sve "T_*_BC" teksture i proveriti da li sve imaju sRGB ukljucen
  3. Pronalazenje -- lako pronadjete sve asset-e odredjenog tipa pretragom prefiksa
  4. Validacija -- automatski skripti mogu da provere da li svaki SM_ ima odgovarajuce T_ teksture

37.8.2 Folder Organizacija

Content/
├── _Dev/                    # Razvoj i testiranje (ne pakuje se)
│   ├── TeamMember1/
│   └── TeamMember2/
│
├── Core/                    # Osnovna logika igre
│   ├── Characters/
│   │   ├── Hero/
│   │   │   ├── Mesh/        # SK_Hero, SKEL_Hero, PHYS_Hero
│   │   │   ├── Animations/  # A_Hero_Walk, A_Hero_Run, AB_Hero
│   │   │   ├── Materials/   # M_Hero_Body, MI_Hero_Skin_Dark
│   │   │   └── Textures/    # T_Hero_Body_BC, T_Hero_Body_N
│   │   └── NPCs/
│   │       ├── Guard/
│   │       └── Merchant/
│   │
│   ├── Weapons/
│   │   ├── Rifle/
│   │   │   ├── Mesh/
│   │   │   ├── Materials/
│   │   │   └── Textures/
│   │   └── Sword/
│   │
│   └── Blueprints/          # Gameplay Blueprint-ovi
│
├── Environment/             # Okruzenje
│   ├── Architecture/
│   │   ├── Buildings/
│   │   │   ├── Residential/
│   │   │   │   ├── Meshes/   # SM_House_01, SM_House_02
│   │   │   │   ├── Materials/
│   │   │   │   └── Textures/
│   │   │   └── Industrial/
│   │   └── Props/
│   │       ├── Furniture/
│   │       ├── Debris/
│   │       └── Vehicles/
│   │
│   ├── Nature/
│   │   ├── Trees/
│   │   ├── Rocks/
│   │   ├── Grass/
│   │   └── Terrain/
│   │
│   └── SharedMaterials/     # Materijali deljeni izmedju vise objekata
│       ├── M_Wood_Generic
│       ├── M_Concrete_Generic
│       └── M_Metal_Generic
│
├── Effects/                 # VFX
│   ├── Niagara/
│   ├── Materials/
│   └── Textures/
│
├── Audio/                   # Zvukovi
│   ├── SFX/
│   ├── Music/
│   ├── Ambience/
│   └── MetaSounds/
│
├── UI/                      # Korisnicki interfejs
│   ├── Widgets/
│   ├── Textures/
│   └── Fonts/
│
└── Maps/                    # Nivoi/Mape
    ├── MainMenu/
    ├── Level_01/
    └── Level_02/

Kljucna pravila:

  1. Nikada ne stavljajte asset-e u root Content/ folder -- uvek u odgovarajucu podstrukturu
  2. _Dev/ folder se ne pakuje -- dodajte ga u "Directories to Never Cook" u Project Settings
  3. Drzite mesh, materijale, i teksture zajedno -- za isti objekat, sve u istom folderu
  4. SharedMaterials za deljene resurse -- materijali koji se koriste na vise objekata idu u zajednicki folder
  5. Konzistentna dubina -- nemojte imati neke asset-e 2 foldera duboko a neke 8 foldera duboko

37.8.3 Asset Validation Rules

UE5 podrzava Asset Validation -- sistem za automatsku proveru asset-a pri importu ili na zahtev. Mozete definisati pravila koja moraju da budu zadovoljena da bi asset prosao validaciju.

Ugradjene validacije

UE5 ima neke ugradjene validacije:

Custom validacije (Blueprint ili C++)

Mozete napisati sopstvene validacione skripte:

// Primer: Custom Asset Validator koji proverava da li mesh ima LOD-ove
UCLASS()
class UMyMeshValidator : public UEditorValidatorBase
{
    GENERATED_BODY()

public:
    virtual EDataValidationResult ValidateLoadedAsset_Implementation(
        UObject* InAsset, TArray<FText>& ValidationErrors) override
    {
        UStaticMesh* Mesh = Cast<UStaticMesh>(InAsset);
        if (!Mesh) return EDataValidationResult::NotValidated;

        // Proveri da li mesh ima vise od 1000 trouglova bez LOD-ova
        int32 TriCount = Mesh->GetNumTriangles(0); // LOD0
        int32 LODCount = Mesh->GetNumLODs();

        if (TriCount > 1000 && LODCount <= 1)
        {
            ValidationErrors.Add(FText::Format(
                LOCTEXT("NoLODs", "Mesh {0} ima {1} trouglova ali nema LOD-ove! "
                "Dodajte LOD-ove ili ukljucite Nanite."),
                FText::FromString(Mesh->GetName()),
                FText::AsNumber(TriCount)));
            return EDataValidationResult::Invalid;
        }

        // Proveri maksimalan triangle count
        if (TriCount > 100000 && !Mesh->NaniteSettings.bEnabled)
        {
            ValidationErrors.Add(FText::Format(
                LOCTEXT("TooManyTris", "Mesh {0} ima {1} trouglova bez Nanite-a! "
                "Ukljucite Nanite ili smanjite kompleksnost."),
                FText::FromString(Mesh->GetName()),
                FText::AsNumber(TriCount)));
            return EDataValidationResult::Invalid;
        }

        return EDataValidationResult::Valid;
    }
};
// Primer: Validator za teksture
UCLASS()
class UMyTextureValidator : public UEditorValidatorBase
{
    GENERATED_BODY()

public:
    virtual EDataValidationResult ValidateLoadedAsset_Implementation(
        UObject* InAsset, TArray<FText>& ValidationErrors) override
    {
        UTexture2D* Texture = Cast<UTexture2D>(InAsset);
        if (!Texture) return EDataValidationResult::NotValidated;

        // Proveri maksimalnu rezoluciju
        int32 MaxDim = FMath::Max(Texture->GetSizeX(), Texture->GetSizeY());
        if (MaxDim > 4096)
        {
            ValidationErrors.Add(FText::Format(
                LOCTEXT("TextureTooLarge", "Tekstura {0} je {1}x{2}. "
                "Maksimalna dozvoljena rezolucija je 4096x4096."),
                FText::FromString(Texture->GetName()),
                FText::AsNumber(Texture->GetSizeX()),
                FText::AsNumber(Texture->GetSizeY())));
            return EDataValidationResult::Invalid;
        }

        // Proveri POT dimenzije
        if (!FMath::IsPowerOfTwo(Texture->GetSizeX()) || 
            !FMath::IsPowerOfTwo(Texture->GetSizeY()))
        {
            ValidationErrors.Add(FText::Format(
                LOCTEXT("NotPOT", "Tekstura {0} ({1}x{2}) nema power-of-two "
                "dimenzije. Mip-mape nece raditi optimalno."),
                FText::FromString(Texture->GetName()),
                FText::AsNumber(Texture->GetSizeX()),
                FText::AsNumber(Texture->GetSizeY())));
            return EDataValidationResult::Invalid;
        }

        // Proveri sRGB za normal mape (detektovane po imenu)
        if (Texture->GetName().Contains("_N") || Texture->GetName().Contains("_Normal"))
        {
            if (Texture->SRGB)
            {
                ValidationErrors.Add(FText::Format(
                    LOCTEXT("NormalSRGB", "Tekstura {0} izgleda kao normal mapa "
                    "ali ima ukljucen sRGB! Iskljucite sRGB."),
                    FText::FromString(Texture->GetName())));
                return EDataValidationResult::Invalid;
            }
        }

        return EDataValidationResult::Valid;
    }
};

37.8.4 Automatske Provere

Pored runtime validacija, trebalo bi da imate automatske provere koje se pokrecu u CI/CD pipeline-u (Continuous Integration):

CI/CD Asset Pipeline Checks:

Pre-commit checks (pre nego sto umetnik commituje):
├── Imenovanje: Da li asset prati naming konvenciju?
├── Folder: Da li je u ispravnom folderu?
├── Velicina: Da li je fajl ispod maksimalne velicine?
└── Format: Da li je u podrzanom formatu?

Nightly build checks (svake noci):
├── LOD audit: Koji mesh-evi nemaju LOD-ove?
├── Texture audit: Koje teksture su prevelike?
├── Kompresija: Koje teksture imaju pogresnu kompresiju?
├── Reference check: Koji asset-i imaju broken reference?
├── Unused asset scan: Koji asset-i nisu referencirani?
├── Duplicate detection: Da li postoje duplirani asset-i?
└── Memory budget: Da li su ukupni budzeti zadovoljeni?

Release checks (pre isporuke):
├── Cooked content size: Da li je ukupna velicina u budzetu?
├── Missing assets: Da li nedostaju asset-i?
├── Platform validation: Da li sve radi na svim ciljnim platformama?
└── Performance test: Da li su asset-i u okviru performansnog budzeta?

Editor Utility Widget za Asset Audit

Mozete napraviti Editor Utility Widget (Blueprint-based alat u editoru) koji vas tim koristi za brzi audit:

Editor Utility Widget: "Asset Health Check"

[Dugme: Scan All Meshes]
  --> Lista svih mesh-eva bez LOD-ova i sa >1000 trouglova
  --> Lista svih mesh-eva sa >100K trouglova bez Nanite-a

[Dugme: Scan All Textures]
  --> Lista svih tekstura >4096
  --> Lista svih tekstura sa pogresnom kompresijom
  --> Lista svih normal mapa sa ukljucenim sRGB-om

[Dugme: Scan References]
  --> Lista svih asset-a bez zavisnika (potencijalno nekorisceni)
  --> Lista svih circular dependency-a

[Dugme: Generate Report]
  --> Kreira CSV/JSON sa svim pronadjenim problemima
  --> Salje notifikaciju na Slack/Discord

37.8.5 Content Standards Document

Svaki ozbiljan projekat treba da ima Content Standards Document -- dokument koji definise pravila i standarde za sve asset-e u projektu. Ovo nije tehnicka dokumentacija za engine -- ovo je dokument za vas tim.

Sta treba da sadrzi:

Content Standards Document -- Primer Strukture:

1. Naming Konvencija
   - Prefiksi i suffiksi za sve tipove asset-a
   - Pravila za imenovanje varijanti (_01, _02, _Small, _Large)
   - Zabranjeni karakteri u imenima

2. Folder Struktura
   - Gde ide koji tip asset-a
   - Pravila za pod-foldere
   - _Dev folder politika

3. Mesh Standardi
   - Maksimalan triangle count po kategoriji (hero, prop, background)
   - Obavezan LOD count po kategoriji
   - Pivot point konvencija (centar, dno, custom)
   - Scale konvencija (1 UE unit = 1 cm)
   - Kolizioni standardi

4. Texture Standardi
   - Maksimalna rezolucija po kategoriji
   - Obavezna kompresija po tipu teksture
   - sRGB pravila
   - Channel packing konvencija (sta ide u R, G, B)
   - Naming suffiksi za svaki tip teksture

5. Material Standardi
   - Maksimalan instruction count
   - Maksimalan texture sample count
   - Pravila za Material Instance hijerarhiju
   - Zabranjene operacije u materijalima

6. Animation Standardi
   - Frame rate (30 ili 60 FPS)
   - Remove Redundant Keys: obavezno
   - Naming konvencija za animacije

7. Audio Standardi
   - Sample rate (44100 ili 48000)
   - Format (WAV za import, Vorbis/Opus za runtime)
   - Naming konvencija

8. Proces
   - Ko odobrava import novih asset-a
   - Kako se prijavljuju problemi
   - Kako se radi review asset-a

9. Checklist za Import
   - Lista provera pre importa svakog tipa asset-a

Ovo nije samo birokratija -- Content Standards Document sprecava probleme koji bi inace kostali dane ili nedelje rada. Kada umetnik importuje mesh sa 2 miliona trouglova bez LOD-ova i to zavrsi u finalnom buildu, pronalazenje i resavanje tog problema kosta mnogo vise vremena nego sto bi kostala 30-sekundna provera u momentu importa.


37.9 Napredni Pipeline Koncepti

37.9.1 Automated Import Pipeline

Za velike timove, rucni import svakog asset-a nije skalabilan. UE5 podrzava automatizaciju importa putem:

Editor Scripting (Python/Blueprint):

# Python skripta za automatski import i podesavanje mesh-eva
import unreal

def import_and_setup_static_mesh(fbx_path, destination_folder):
    # Definisi import podesavanja
    task = unreal.AssetImportTask()
    task.filename = fbx_path
    task.destination_path = destination_folder
    task.automated = True  # Ne prikazuj dijalog
    task.replace_existing = True
    
    # FBX import opcije
    options = unreal.FbxImportUI()
    options.import_mesh = True
    options.import_textures = True
    options.import_materials = True
    
    # Mesh opcije
    options.static_mesh_import_data.combine_meshes = False
    options.static_mesh_import_data.generate_lightmap_u_vs = True
    options.static_mesh_import_data.auto_generate_collision = True
    options.static_mesh_import_data.remove_degenerates = True
    
    task.options = options
    
    # Izvrsi import
    unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task])
    
    # Posle importa -- podesi LOD-ove
    imported_asset = unreal.load_asset(
        destination_folder + "/" + task.imported_object_paths[0])
    
    if isinstance(imported_asset, unreal.StaticMesh):
        # Generisi 3 LOD nivoa
        lod_settings = unreal.EditorStaticMeshLibrary
        lod_settings.set_lod_count(imported_asset, 4)
        
        # Podesi screen size za svaki LOD
        # LOD0: default (1.0)
        # LOD1: 0.5
        # LOD2: 0.25
        # LOD3: 0.12
        
    unreal.log("Import zavrsen: " + fbx_path)

Data-Driven Import:

Napravite CSV ili JSON fajl koji definise import pravila za svaki asset:

{
  "import_rules": [
    {
      "pattern": "SM_*_Hero_*",
      "settings": {
        "build_nanite": true,
        "lod_count": 4,
        "collision": "simple_box",
        "max_texture_size": 4096
      }
    },
    {
      "pattern": "SM_*_Prop_*",
      "settings": {
        "build_nanite": false,
        "lod_count": 3,
        "collision": "auto_convex",
        "max_texture_size": 2048
      }
    },
    {
      "pattern": "SM_*_Background_*",
      "settings": {
        "build_nanite": false,
        "lod_count": 4,
        "collision": "simple_box",
        "max_texture_size": 1024
      }
    }
  ]
}

37.9.2 Hot Folder Workflow

Neki timovi koriste "hot folder" pristup -- folder na disku koji se automatski skenira za nove FBX/teksture fajlove. Kada se novi fajl pojavi, automatski se importuje sa predefinisanim podesavanjima.

Workflow:
1. Umetnik exportuje FBX iz Blender-a u hot folder
2. Editor detektuje novi fajl (putem FDirectoryWatcher)
3. Automatski import sa pravilima na osnovu naming konvencije
4. Automatska LOD generacija
5. Automatska validacija
6. Notifikacija umetniku: "SM_Chair_01 importovan, 3 LOD-a generisana, 
   validacija: PASSED"

37.9.3 USD (Universal Scene Description) Pipeline

USD je relativno novi format za razmenu 3D sadrzaja, razvijen od strane Pixar-a. UE5 ima rastuce podrzavanje za USD, i mnogi studiji prelaze na USD-based pipeline-ove.

Prednosti USD-a nad FBX-om:

USD Pipeline primer:
1. Layout artist kreira scenu u Maya/Houdini kao USD
2. Svaki asset je zasebna USD referenca
3. Izmenama na jednom asset-u automatski se azuriraju sve scene
4. UE5 ucitava USD scenu sa svim referencama
5. Promena u DCC alatu --> automatski re-import u UE5 (live link)

37.9.4 Texture Pipeline Automatizacija

Za teksture, cest je sledeceautomatizovani workflow:

Substance Painter/Designer
         |
         v
Export textures (PNG/TGA, naming konvencija)
         |
         v
Post-processing skripta:
├── Channel packing (R=AO, G=Roughness, B=Metalness --> ORM)
├── Resize (po pravilima iz standards dokumenta)
├── POT check (dimenzije moraju biti power of two)
└── Naming validation
         |
         v
Import u UE5 (automatski ili rucni)
         |
         v
UE5 post-import:
├── Kompresija (automatski na osnovu suffiksa)
├── sRGB podesavanje (automatski na osnovu suffiksa)
├── LOD Group assignment
└── Validacija

37.10 Studija Slucaja: Asset Pipeline u Praksi

Da bismo sve ovo povezali, pogledajmo konkretan primer pipeline-a za jedan asset od pocetka do kraja.

Scenario: Importovanje industrijskog ventilatora

Asset: Industrijski ventilator na zidu fabricke hale
Upotreba: Prop u pozadini, igrac prolazi pored na ~5-20m
Platforma: PC (DX12), cilj 60 FPS

Korak 1: Planiranje
-------------------------------------------------
Na osnovu Content Standards dokumenta:
- Kategorija: Props > Industrial
- Naming: SM_Prop_IndustrialFan_01
- Triangle budget: LOD0 max 8,000
- Texture budget: 2048x2048 za BC, N, ORM
- LOD-ovi: minimum 3
- Kolizija: simple box (igrac ne interaguje direktno)

Korak 2: Modelovanje (Blender)
-------------------------------------------------
- High-poly model: 150,000 trouglova (za baking)
- Low-poly (game mesh): 6,200 trouglova
- UV unwrap: 1 UV set za teksture, 2. UV set za lightmap
- Export: FBX, centimetri, Y-up (UE5 konverzija)

Korak 3: Texturing (Substance Painter)
-------------------------------------------------
- Export teksture:
  T_Prop_IndustrialFan_01_BC.png   (2048, sRGB)
  T_Prop_IndustrialFan_01_N.png    (2048, linear)
  T_Prop_IndustrialFan_01_ORM.png  (2048, linear, packed R=AO, G=Roughness, B=Metal)

Korak 4: Import u UE5
-------------------------------------------------
Mesh import settings:
  - Auto Generate Collision: OFF (koristicemo simple box)
  - Generate Lightmap UVs: OFF (vec imamo UV1 iz Blender-a)
  - Build Nanite: OFF (6,200 trouglova, ne treba Nanite)
  - Remove Degenerates: ON
  - Normal Import Method: Import Normals and Tangents

Texture import:
  T_*_BC: Compression = Default (BC1), sRGB = ON
  T_*_N:  Compression = Normalmap (BC5), sRGB = OFF
  T_*_ORM: Compression = Masks (no sRGB), sRGB = OFF

Korak 5: Post-Import Setup u UE5
-------------------------------------------------
LOD generacija:
  LOD0: 6,200 tri (original)      Screen Size: 1.0
  LOD1: 3,100 tri (50%)           Screen Size: 0.4
  LOD2: 1,200 tri (80% redukcija) Screen Size: 0.15
  
  Vizuelna provera svakog LOD-a: OK

Kolizija:
  Add Box Simplified Collision
  Podesi velicinu box-a da okruzi mesh

Materijal:
  M_Prop_IndustrialFan_01
  - Base Color: T_*_BC
  - Normal: T_*_N
  - ORM: T_*_ORM (R -> AO, G -> Roughness, B -> Metalness)

Korak 6: Validacija
-------------------------------------------------
Automatski validator:
  [PASS] Naming konvencija: SM_Prop_IndustrialFan_01
  [PASS] Triangle count: 6,200 (budget: 8,000)
  [PASS] LOD count: 3 (minimum: 3)
  [PASS] Texture size: 2048 (max: 2048)
  [PASS] Texture compression: BC1, BC5, BC1 (correct)
  [PASS] Normal map sRGB: OFF
  [PASS] Collision: present

Memory footprint:
  Mesh (svi LOD-ovi): ~0.4 MB
  Teksture: BC=2.7MB + N=5.5MB + ORM=2.7MB = ~10.9 MB
  UKUPNO: ~11.3 MB

Korak 7: Testiranje u Sceni
-------------------------------------------------
  Stavite ventilator u scenu na tipicnu poziciju
  Prodjite pored: LOD tranzicije glatke, bez popping-a
  FPS uticaj: nemerljiv (ocekivano za mali prop)
  Vizuelni kvalitet: zadovoljavajuci na svim distancama
  
  STATUS: Asset odobren za produkciju.

37.11 Kljucni Pojmovi

Termin Definicija
Asset Pipeline Proces pripreme i optimizacije sadrzaja od DCC alata do engine-a -- ukljucuje export, import, processing i validaciju
DCC (Digital Content Creation) Alati za kreiranje sadrzaja: Blender, Maya, ZBrush, Substance, Houdini
FBX Autodesk-ov format za razmenu 3D podataka; de facto standard za game dev
USD (Universal Scene Description) Pixar-ov otvoreni format za razmenu 3D scena; sve popularniji u game dev-u
LOD (Level of Detail) Tehnika koriscenja manje detaljnih verzija mesh-a za udaljene objekte
LOD0 Najdetaljniji nivo mesh-a (originalni mesh); prikazuje se kada je objekat najblize kameri
Screen Size Procenat ekrana koji mesh zauzima; koristi se za odredjivanje koji LOD nivo prikazati
Mesh Reduction / Decimation Proces smanjivanja broja poligona u mesh-u uz ocuvanje vizuelnog kvaliteta
Edge Collapse Algoritam mesh redukcije koji spaja dva verteksa ivice u jedan vertex
Quadric Error Metric (QEM) Matematicka metrika za procenu cene kolapsa ivice; minimizuje vizuelnu promenu
Retopologija Proces kreiranja novog, optimizovanog mesh-a na osnovu high-poly modela
UV Seam Linija gde se UV mapping "sece"; mora se pazljivo ocuvati tokom mesh redukcije
Material Boundary Granica izmedju razlicitih materijala na mesh-u; kolaps na granici menja materijal raspored
Silhouette Kontura/obris mesh-a; kriticna za prepoznatljivost na udaljenim LOD nivoima
BC1 (DXT1) GPU format kompresije tekstura; 4 bita po pikselu, za RGB bez alpha
BC3 (DXT5) GPU format kompresije; 8 bita po pikselu, za RGBA (boja sa alpha kanalom)
BC5 GPU format kompresije; 8 bita po pikselu, za dvokanalske podatke (normal mape)
BC7 GPU format kompresije; 8 bita po pikselu, najvisi kvalitet blok kompresije
BC6H GPU format kompresije za HDR teksture; 8 bita po pikselu
ASTC Adaptive Scalable Texture Compression; fleksibilan format za mobilne GPU-ove
ETC2 Ericsson Texture Compression; legacy format za mobilne platforme
Channel Packing Tehnika pakovanja vise grayscale tekstura u kanale (R,G,B,A) jedne teksture
ORM Channel-packed tekstura: R=Ambient Occlusion, G=Roughness, B=Metalness
sRGB Gamma color space koristen za boje koje ljudsko oko vidi; mora biti iskljucen za podatkovne teksture
LOD Bias Podesavanje koje pomera koji mip nivo se koristi; veci bias = manja efektivna rezolucija
LOD Group Grupa tekstura koje menjaju rezoluciju zajedno
Mip-mape Prethodno izracunate manje verzije teksture za razlicite distancije od kamere
Power of Two (POT) Dimenzije teksture koje su stepen dvojke (256, 512, 1024...); optimalne za GPU
Size Map UE5 alat koji vizualizuje velicinu asset-a kao treemap dijagram
Reference Viewer UE5 alat koji prikazuje graf zavisnosti izmedju asset-a
Asset Audit Proces pregleda svih asset-a u projektu za pronalazenje problema
Content Standards Document Dokument koji definise pravila i standarde za sve asset-e u projektu
Simplygon Microsoft-ov profesionalni alat za mesh optimizaciju; besplatan za UE5 korisnike
InstaLOD Profesionalni alat za mesh redukciju, remeshing i LOD generaciju
Cooking Proces konverzije editor asset-a u format optimizovan za ciljnu platformu
Vertex Welding Spajanje blizih verteksa u jedan; smanjuje vertex count ali moze da promeni oblik
Convex Hull Najmanji konveksni oblik koji okruzuje mesh; koristi se za koliziju
Hard Reference Direktna referenca na asset koja uzrokuje automatsko ucitavanje (vidi poglavlje 36)
Soft Reference Referenca kao putanja; asset se ne ucitava automatski, vec na zahtev (vidi poglavlje 36)
Progressive Mesh Tehnika koja omogucava kontinuirani LOD kroz niz edge collapse operacija
Vertex Clustering Brz ali grub algoritam mesh redukcije zasnovan na podeli prostora na celije

37.12 Povezana Poglavlja u Ovoj Knjizi


37.13 Korisni Linkovi i Dalje Citanje

Zvanicna Unreal Engine Dokumentacija

Tehnicke Prezentacije

Akademski Radovi

Knjige

Alati


Rezime Poglavlja

Asset pipeline je nevidljivi heroj (ili zlikovac) performansa vase igre. Sve ono sto se desava pre renderinga -- import, kompresija, LOD generacija, validacija -- definise granice onoga sto rendering moze da postigne.

Import je prvi kritican korak: pravilna FBX podesavanja, ispravna kompresija tekstura, generisanje lightmap UV-ova i LOD-ova pri importu. Greske napravljene ovde se propagiraju kroz ceo projekat.

LOD generacija drasticno smanjuje rendering cost za udaljene objekte. UE5-ova automatska generacija je dovoljno dobra za vecinu asset-a, ali za kriticne objekte (likovi, hero props) rucni LOD-ovi su neophodni. Za high-poly staticne mesh-eve, Nanite (poglavlje 30) eliminise potrebu za rucnim LOD-ovima.

Mesh redukcija koristi algoritme poput edge collapse-a sa Quadric Error Metric-om da smanji kompleksnost mesh-a uz minimalan vizuelni gubitak. Kljuc je u ocuvanju UV seam-ova, material boundary-a i siluete.

Texture compression je mozda najvaznija pojedinacna optimizacija -- pravilna kompresija moze da smanji VRAM potrosnju 4-8x bez primetnog gubitka kvaliteta. BC1 za boje, BC5 za normal mape, channel packing za maske.

Asset audit je kontinuirani proces -- koristite Size Map, Reference Viewer i Asset Audit alate da pronadjete i resavate probleme pre nego sto postanu kriticni.

Best practices -- naming konvencije, folder organizacija, Content Standards Document, automatske validacije -- nisu "birokratija". Oni su razlika izmedju projekta koji se odrzava lako i projekta koji postaje neodrziv posle 6 meseci.

Zapamtite: rendering moze da radi samo sa onim sto mu date. Dajte mu optimizovane asset-e, i imaace prostora da bude briljantno. Dajte mu haos, i nikakva rendering optimizacija nece pomoci.