Poglavlje 3: Mesh i topologija

Poglavlje 3: Mesh i topologija

U ovom poglavlju učiš šta je zapravo 3D model — od čega je napravljen, kako je organizovan, i kako GPU čuva geometriju u memoriji. Razumećeš zašto se koriste trouglovi, šta je dobra a šta loša topologija, kako rade normale, i kako vertex i index bufferi omogućavaju efikasno renderovanje.


Šta je mesh?

Kad čuješ "3D model", verovatno zamisliš gotov objekat — auto, lik, drvo, zgradu. Ali iz perspektive računara, 3D model je samo kolekcija tačaka u prostoru, povezanih linijama koje formiraju površine. Ta kolekcija tačaka i površina je mesh (mreža).

Zamislite žičanu skulpturu. Imate gomilu tačaka u prostoru gde se žice ukrštaju, žice koje ih spajaju, i ravne površine razapete između žica. To je suštinski mesh:

Ova tri elementa — vertices, edges, faces — čine osnovnu strukturu svakog 3D mesh-a.


Vertex (teme)

Vertex je fundamentalna jedinica 3D geometrije — tačka u 3D prostoru definisana koordinatama (x, y, z).

Ali vertex u modernoj grafici je mnogo više od samo pozicije. Svaki vertex nosi dodatne podatke — atribute — koji su neophodni za pravilno renderovanje:

Vertex atributi

Pozicija (Position) — (x, y, z) koordinate u lokalnom prostoru objekta. Ovo je jedini obavezni atribut.

Normala (Normal) — vektor koji pokazuje u kom pravcu "gleda" površina u tom temenu. Ključno za osvetljenje. Detaljno ćemo obraditi normalne u ovom poglavlju.

UV koordinate (Texture Coordinates) — koordinate koje govore kako se tekstura "preslikava" na površinu. Obično (u, v) par u opsegu 0-1. Detaljno u poglavlju 4.

Tangent i Bitangent — vektori u ravni površine, okomiti na normalu. Potrebni za normal mapping (poglavlje 19). Tangent, bitangent i normala zajedno formiraju TBN matricu.

Vertex boja (Vertex Color) — RGBA boja pridružena verteksu. Koristi se za razne namene: blending materijala, maskiranje, painted vertex colors za vegetation.

Bone weights i indices — za skeletal mesh-eve (animirane likove), svaki vertex zna koje kosti na njega utiču i koliko (weight). Tipično do 4 ili 8 kostiju po verteksu.

Dodatni UV setovi — mesh može imati više UV kanala. Čest primer: UV0 za teksture materijala, UV1 za lightmap. UE5 podržava do 8 UV kanala.

Svaki od ovih atributa zauzima memoriju. Tipičan vertex u modernoj igri može da zauzme 32-64 bajta. Kad imaš mesh sa 100.000 verteksa, to je 3-6 MB samo za vertex podatke. Stotine mesh-eva u sceni — i to se sabira brzo.

Vertex u memoriji

Vertex podaci se čuvaju u Vertex Buffer — linearnom nizu memorije na GPU-u (VRAM). Postoje dva pristupa organizaciji:

Interleaved (AoS — Array of Structures):

[Pos₀, Normal₀, UV₀, Tangent₀] [Pos₁, Normal₁, UV₁, Tangent₁] [Pos₂, ...]

Svi atributi jednog verteksa su zajedno u memoriji.

Separate streams (SoA — Structure of Arrays):

Buffer 1: [Pos₀, Pos₁, Pos₂, ...]
Buffer 2: [Normal₀, Normal₁, Normal₂, ...]
Buffer 3: [UV₀, UV₁, UV₂, ...]

Svaki atribut ima svoj buffer.

Koji je bolji? Zavisi. Interleaved je bolji kad GPU čita sve atribute za svaki vertex (cache-friendly za taj vertex). Separate streams su bolji kad neka faza pipeline-a treba samo neke atribute — na primer, shadow pass treba samo pozicije, ne i normale i UV-e. UE5 koristi kombinovani pristup — pozicija je u jednom bufferu, ostali atributi u drugom.


Edge (ivica)

Edge je linija koja spaja dva verteksa. Edges definišu "skeleton" mesh-a — konture i ivice objekata.

Edge sam po sebi ne renderuje — GPU ne crta ivice (osim u wireframe debug modu). Ali edges su fundamentalni za topologiju — kako su faces organizovani i povezani.

Boundary vs Interior edges

Boundary (graničan) edge — pripada samo jednom face-u. Ako mesh ima boundary edges, ima "rupu" — nije zatvoren. Zamislite čašu bez dna — ivica dna je boundary edge.

Interior (unutrašnji) edge — deli dva face-a. Većina edges u zatvorenom mesh-u su interior.

Non-manifold edge — deli tri ili više face-ova. Ovo je problematičan slučaj o kom ćemo detaljno govoriti u sekciji o topologiji.


Face (strana/lice)

Face je ravna površina definisana sa tri ili više verteksa. Face je ono što zapravo vidimo kad renderujemo — to je površina koja se "boji", prima svetlost, i prikazuje teksture.

Trouglovi — zašto baš tri?

Ovo je jedno od najvažnijih pitanja u 3D grafici: zašto su trouglovi osnovna jedinica renderovanja? Zašto ne kvadrati, petouglovi, ili proizvoljni poligoni?

1. Trougao je uvek ravan (planar)

Tri tačke u prostoru uvek definišu jednu ravnu površinu — matematički je nemoguće da tri tačke formiraju zakrivljenu površinu (osim ako su kolinearne — na istoj pravoj, što je degenerisan slučaj). Ali četiri tačke mogu da ne budu koplanarne — zamislite da pomerate jedan ugao kvadrata gore-dole. Sada imate "savijeni" kvadrat koji nije ravan.

Zašto je to bitno? Jer rasterizer (deo GPU-a koji pretvara geometriju u piksele) radi sa ravnim površinama. Ako mu daš neravnu površinu, ne zna kako da je obradi. Trouglovi garantuju ravnost.

2. Trougao ima jedinstven "unutra"

Za svaki trougao, jasno je definisano šta je unutra a šta spolja — svaka tačka na ekranu je ili unutar trougla ili van njega (ili na ivici). Ovo je ključno za rasterizaciju — GPU mora da zna koje piksele da "oboji". Za konveksne poligone ovo važi, ali za konkavne (one sa "uvučenim" uglovima) — ne, i to komplikuje stvari.

3. Trougao je najjednostavniji poligon

Trougao je poligon sa najmanjim mogućim brojem ivica. Ne možeš imati poligon sa manje od tri temena i tri ivice. Ova jednostavnost omogućava najefikasnije hardverske implementacije.

4. Barycentric interpolacija

Trouglovi omogućavaju elegantnu interpolaciju atributa (boja, UV koordinate, normale) preko površine koristeći baricentrične koordinate. Ovo je fundamentalno za rasterizaciju i detaljno je objašnjeno u poglavlju 9.

5. GPU je optimizovan za trouglove

Moderni GPU-i su bukvalno dizajnirani sa trouglo-centrinim pipeline-om. Svaka faza hardvera — od vertex processing-a, preko rasterizacije, do pixel shading-a — je optimizovana za trouglove. Promeni li se ovo jednog dana? Možda — Nanite u UE5 interno koristi mikro-trouglove koji su toliko mali da su praktično tačke, što na neki način zamagljuje granicu. Ali za sada, trougao je kralj.

Poligoni sa više od tri temena

U 3D modelovanju (Blender, Maya, 3ds Max), koristiš poligone sa četiri temena (quad — četvorougao) jer su bolji za modelovanje, subdiviziju i animaciju. Ali kad se model importuje u game engine, svi poligoni se automatski konvertuju u trouglove — proces zvan triangulacija (triangulation).

Quad se deli na dva trougla. Pentagon (petougaonik) na tri trougla. N-gon (poligon sa N temena) na N-2 trougla. Način na koji se quad podeli na dva trougla može da utiče na izgled — posebno na zaobljenim površinama gde je shading osetljiv na topologiju.


Topologija

Topologija mesh-a je način na koji su verteksi, edges i faces organizovani — kako su "umreženi". Dva mesh-a mogu da predstavljaju isti oblik ali da imaju potpuno različitu topologiju — i ta razlika dramatično utiče na kvalitet renderovanja, animacije i performanse.

Dobra vs loša topologija

Dobra topologija ima sledeće karakteristike:

  1. Koristi pretežno quadove (za modelovanje): Quadovi su bolji za subdivision surface modeling i za deformaciju tokom animacije. Kad se animira lik, quadovi se deformišu predvidivo i glatko, dok trouglovi mogu da uzrokuju neprijatne artefakte ("pinching").

  2. Edge flow prati oblik: Edges treba da prate prirodne konture objekta. Na licu lika, edges treba da se "slažu" sa mišićima — oko očiju, usta, nosa. Ovo osigurava da se mesh lepo deformiše kad se lice animira.

  3. Ravnomerna gustina: Verteksi treba da budu ravnomerno raspoređeni, sa više detalja tamo gde je potrebno (lice, šake) i manje gde nije (ravna površina leđa).

  4. Nema nepotrebne geometrije: Svaki vertex, edge i face treba da doprinosi obliku. Nepotrebna geometrija troši memoriju i processing time.

Loša topologija uzrokuje probleme:

  1. Triangulacioni artefakti: Neravnomerni ili nepravilni trouglovi mogu da uzrokuju shading artefakte — nepravilno osvetljenje, vidljive ivice na zaobljenim površinama.

  2. Deformacioni problemi: Loš edge flow uzrokuje "čupanje" i neprirodan izgled kad se mesh animira.

  3. Teškoće sa UV mapping-om: Loša topologija otežava kreiranje čistog UV layout-a.

  4. Performansni problemi: Prekomerna geometrija (previše verteksa za dati detalj) troši resurse bez vizuelnog benefita.

N-goni

N-gon je poligon sa više od 4 temena. N-goni su generalno problematični za real-time grafiku:

Generalno pravilo: u game-ready modelima, n-goni treba da budu samo na savršeno ravnim površinama gde triangulacija ne utiče na izgled. Na zaobljenim površinama — nikad.

Poles

Pole je vertex gde se spaja više od četiri edge-a (u quad-baziranoj topologiji, gde je "normalan" broj 4). Poles sa 3 edge-a (tri-pole) i 5 edge-ova (extraordinary vertex) su uobičajeni i uglavnom u redu. Poles sa 6 ili više edge-ova mogu da uzrokuju artefakte i treba ih izbegavati na zakrivljenim površinama.

Manifold vs Non-manifold geometrija

Manifold geometrija je "fizički moguća" — svaki edge deli tačno dva face-a (ili jedan, za boundary edges), i oko svakog verteksa face-ovi formiraju jedinstven "fan" (lepezu).

Non-manifold geometrija uključuje situacije koje su fizički nemoguće:

  1. Edge deli tri ili više face-ova — zamislite tri strane koje se spajaju na jednoj ivici, kao slovo T. To je fizički nemoguće za "pravo" telo.

  2. Bowtie vertex — dva odvojena dela mesh-a dele jedan vertex. Zamislite dva dijamanta koji se dodiruju samo u jednoj tački.

  3. Duplicirani faces — dva identična trougla jedan na drugom.

  4. Face sa nultom površinom — degenerisan trougao gde su sva tri temena na istoj liniji.

Non-manifold geometrija uzrokuje probleme za:

Većina game engine-a i alata za modelovanje ima opcije za detekciju i popravljanje non-manifold geometrije. To je jedan od prvih koraka u pripremi modela za real-time upotrebu.


Vertex normali — kako mesh "laže" o svom obliku

Ovo je jedan od najvažnijih koncepata u 3D grafici, a istovremeno jedan od najčešće pogrešno shvaćenih.

Problem: ravni trouglovi, zaobljeni objekti

Sferu možeš da aproksimiraš sa trouglovima — mnogo malih ravnih trouglova koji zajedno formiraju okrugao oblik. Ali ako osvetliš svaki trougao na osnovu njegove geometrijske normale (normala ravni trougla), dobijaš jasno vidljive ivice između trouglova — facetiran izgled. Lopta izgleda kao diskotečna kugla, ne kao glatka sfera.

Rešenje: vertex normali.

Šta su vertex normali?

Umesto da svaki trougao ima jednu normalu za celu površinu (face normal), svaki vertex ima svoju normalu. Kad shader izračunava osvetljenje za piksel unutar trougla, normala u tom pikselu se dobija interpolacijom između normala tri temena trougla (koristeći baricentrične koordinate).

Ovo znači da normala varira glatko preko površine trougla, čak i kad je sam trougao savršeno ravan. Rezultat: osvetljenje se menja glatko i ne vide se oštre ivice — objekat izgleda zaobljeno.

Kako se izračunavaju vertex normali?

Najjednostavniji pristup: vertex normala se izračunava kao prosek normala svih trouglova koji dele taj vertex.

Na primer, ako vertex V pripada trouglovima T₁, T₂, T₃, čije su face normali N₁, N₂, N₃:

Vertex normal(V) = normalize(N₁ + N₂ + N₃)

U praksi, prosek je često weighted — ponderisan površinom trougla ili uglom koji trougao zauzima oko tog verteksa, što daje bolje rezultate. Veći trouglovi ili trouglovi koji zauzimaju veći ugao imaju veći uticaj na vertex normalu.

Hard edges vs Soft edges

Ponekad NE želiš glatko osvetljenje. Na primer, ivica kutije treba da bude oštra — ne želiš da se osvetljenje glatko preliva sa jedne strane na drugu.

Rešenje: hard edge (oštra ivica). Na hard edge-u, verteksi se dupliraju — na istoj poziciji postoje dva (ili više) verteksa, svaki sa svojom normalom. Jedan vertex ima normalu koja gleda u pravcu jednog face-a, drugi ima normalu drugog face-a.

Za GPU, ovo su različiti verteksi koji su slučajno na istoj poziciji. Shader interpolira normale unutar svakog trougla, ali pošto trouglovi sa različitih strana edge-a imaju vertekse sa potpuno različitim normalama, nema glatkog prelaza — ivica je oštra.

Soft edge (glatka ivica) je suprotno — verteksi se dele između trouglova i imaju zajedničku normalu (prosek). Osvetljenje se glatko preliva.

Smoothing groups

U alatima za 3D modelovanje, koncept hard/soft edges je organizovan kroz smoothing groups. Trouglovi koji pripadaju istoj smoothing grupi imaju glatke ivice između sebe. Trouglovi u različitim grupama imaju oštre ivice.

Na primer, na kutiji: svih 6 strana je u različitim smoothing grupama — sve ivice su oštre. Na sferi: svi trouglovi su u istoj grupi — sve ivice su glatke.

Na obliku poput cilindra: ravna gornja površina je jedna grupa, ravna donja je druga, zakrivljena strana je treća. Ivice između vrha i strane su oštre, ali ivice između trouglova na samoj strani su glatke.

Uticaj na vertex count

Ovo je čest izvor konfuzije: "moj model ima 1000 verteksa u Blender-u, ali Unreal kaže da ima 2500!"

Razlog su hard edges (i UV seams, i vertex color boundaries). Svaki put kad vertex mora da ima različite atribute na različitim stranama, GPU ga mora duplirati. Vertex na hard edge-u postaje dva verteksa. Vertex na UV seam-u postaje dva verteksa.

Dakle, "geometrijski" vertex count (koliko jedinstvenih pozicija postoji) i "renderovani" vertex count (koliko verteksa GPU zapravo obrađuje) su različite stvari. Za performanse je bitan renderovani count.

Česta greška: modelar pravi model "sa malo verteksa" ali sa mnogo hard edges i UV seams-ova, pa renderovani count bude daleko veći nego očekivano. Ovo treba imati na umu pri optimizaciji.


Winding order — redosled temena

Kad definišeš trougao, navodiš tri temena: V₀, V₁, V₂. Ali redosled kojim ih navodiš je bitan — on određuje na koju stranu gleda trougao.

Counter-clockwise (CCW) winding — ako gledaš trougao spreda, temena idu u smeru suprotnom od kazaljke na satu. Ovo je konvencija u OpenGL-u i većini 3D softvera.

Clockwise (CW) winding — temena idu u smeru kazaljke na satu. Ovo je konvencija u DirectX-u i UE5.

Normala trougla se izračunava cross productom:

N = (V₁ - V₀) × (V₂ - V₀)

Ako promeniš redosled temena, cross product menja znak, i normala gleda u suprotnom smeru. Trougao sada "gleda" na drugu stranu.

Back-face culling

GPU koristi winding order za back-face culling — brzu eliminaciju trouglova koji su okrenuti od kamere. Ako su temena projektovanog trougla (na ekranu) u pogrešnom redosledu (npr. CW kad se očekuje CCW), trougao je okrenut od kamere i ne treba da se crta.

Ovo eliminše otprilike polovinu svih trouglova u sceni, značajno ubrzavajući renderovanje. Ali ovo znači da modeli moraju da imaju konzistentan winding order — ako su neki trouglovi CW a neki CCW, delovi modela će nestati kad budu okrenuti ka kameri.

Čest problem pri importu modela iz različitih softvera: redosled temena može da se obrne (jer se menja koordinatni sistem), i normali pokazuju na pogrešnu stranu. Rezultat: delovi modela su "nevidljivi" — zapravo su vidljivi samo sa unutrašnje strane.

Double-sided rendering

Ponekad hoćeš da se obe strane trougla crtaju — na primer, za listove drveća koji su modelovani kao ravne ploče, ili za tanke objekte poput papira. U tom slučaju, isključuješ back-face culling za taj materijal (u UE5: "Two Sided" opcija na materijalu). Ovo znači da se svaki trougao renderuje dva puta — jednom za svaku stranu — pa je skuplje, ali neophodan za neke slučajeve.


Kako GPU čuva mesh u memoriji

Sad kad razumeš šta čini mesh, hajde da vidimo kako GPU zapravo organizuje te podatke u memoriji. Ovo je ključno za razumevanje performansi.

Vertex Buffer

Vertex buffer je linearan niz memorije na GPU-u (VRAM) koji čuva sve vertex atribute. Zamislite ga kao ogromnu Excel tabelu gde je svaki red jedan vertex, a kolone su pozicija, normala, UV, itd.

Index | Position        | Normal          | UV0        | Tangent
------+-----------------+-----------------+------------+---------
  0   | (1.0, 2.0, 3.0) | (0.0, 1.0, 0.0) | (0.5, 0.5) | (1.0, 0.0, 0.0)
  1   | (4.0, 2.0, 3.0) | (0.0, 1.0, 0.0) | (1.0, 0.5) | (1.0, 0.0, 0.0)
  2   | (1.0, 2.0, 6.0) | (0.0, 1.0, 0.0) | (0.5, 1.0) | (1.0, 0.0, 0.0)
  ...

Index Buffer — zašto postoji i kako radi

Evo ključnog pitanja: kako GPU zna koji verteksi formiraju koji trougao?

Naivan pristup (bez index buffer-a): Za svaki trougao, nabroji tri verteksa:

Trougao 0: V₀, V₁, V₂
Trougao 1: V₃, V₄, V₅
Trougao 2: V₆, V₇, V₈
...

Problem: mnogi trouglovi dele iste vertekse. Quad (dva trougla) ima 4 jedinstvena verteksa, ali bez index buffer-a mora da čuva 6 (dva su duplikat). Za kompleksan mesh, duplikacija je ogromna.

Index buffer pristup: Čuvaj svaki jedinstven vertex samo jednom u vertex buffer-u. Index buffer čuva indekse (redne brojeve) verteksa koji čine svaki trougao:

Vertex buffer:

0: V₀ = (0, 0, 0, ...)
1: V₁ = (1, 0, 0, ...)
2: V₂ = (1, 1, 0, ...)
3: V₃ = (0, 1, 0, ...)

Index buffer (dva trougla koji formiraju quad):

Trougao 0: 0, 1, 2
Trougao 1: 0, 2, 3

Verteksi 0 i 2 se dele između dva trougla, ali se čuvaju samo jednom! Index buffer čuva samo 6 indeksa (tipično 16-bit ili 32-bit integer svaki) umesto 6 kompletnih verteksa.

Ušteda memorije i propusnog opsega

Za tipičan mesh:

Ako mesh ima 10.000 verteksa i 18.000 trouglova (54.000 indeksa):

Index buffer smanjuje memoriju za skoro 4.5x u ovom primeru. Za veće mesh-eve, ušteda je još veća jer je odnos deljenih verteksa veći.

Ali memorija nije jedini benefit. Kad GPU obradi vertex (kroz vertex shader), rezultat se čuva u post-transform vertex cache. Kad sledeći trougao referencira isti vertex (isti index), GPU ne mora ponovo da ga obradi — čita rezultat iz cache-a. Ovo značajno smanjuje količinu posla za vertex shader.

Optimizacija redosleda indeksa

Redosled u kom se trouglovi navode u index buffer-u utiče na performanse jer utiče na efikasnost post-transform vertex cache-a. Ako uzastopni trouglovi dele vertekse, cache je efikasniji. Ako su trouglovi u nasumičnom redosledu, svaki zahteva nove vertekse.

Algoritmi poput Tom Forsyth's vertex cache optimization i Tipsy's algorithm reorganizuju redosled trouglova u index buffer-u da maksimizuju cache efikasnost. Većina 3D softvera i game engine-a automatski ovo radi pri importu mesh-a.

16-bit vs 32-bit indeksi

Index buffer može da koristi 16-bitne ili 32-bitne indekse:

Ako mesh ima manje od 65.536 verteksa (velika većina game mesh-eva), 16-bit indeksi su dovoljni i efikasniji. Za veće mesh-eve, potrebni su 32-bit.

UE5 automatski bira format na osnovu veličine mesh-a.


Triangle strips i triangle fans

Osim standardnog "triangle list" formata (gde svaki trougao ima tri eksplicitna indeksa), postoje i efikasniji formati:

Triangle strip

U triangle strip-u, svaki novi trougao deli dve temena sa prethodnim:

Verteksi: V₀, V₁, V₂, V₃, V₄, V₅
Trouglovi:
  T₀ = V₀, V₁, V₂
  T₁ = V₂, V₁, V₃  (deli V₁ i V₂ sa T₀)
  T₂ = V₂, V₃, V₄  (deli V₂ i V₃ sa T₁)
  T₃ = V₄, V₃, V₅  (deli V₃ i V₄ sa T₂)

Za N trouglova, treba N+2 verteksa umesto 3N. Za dugačak strip, to je skoro 3x manje indeksa.

Winding order alternira za uzastopne trouglove (CW, CCW, CW, CCW...) da bi normale bile konzistentne.

Triangle fan

U triangle fan-u, svi trouglovi dele jedno zajedničko teme:

Trouglovi:
  T₀ = V₀, V₁, V₂
  T₁ = V₀, V₂, V₃
  T₂ = V₀, V₃, V₄

Korisno za krug-like geometriju (kapa cilindra, na primer).

Moderni pristup

U modernoj grafici, triangle list sa index buffer-om i vertex cache optimizacijom je dominantan format. Triangle strip-ovi su korisni u specifičnim situacijama, ali opšti mesh-evi se teško optimalno konvertuju u strip-ove. GPU hardver je optimizovan za indeksirane triangle liste.


Mesh complexity — kako meriti

Kako znaš da li je mesh "prevelik" za real-time renderovanje? Postoji nekoliko metrika:

Vertex count i Triangle count

Najočiglednija metrika. Ali koliko je "previše"?

Ne postoji univerzalan odgovor — zavisi od:

Nekad se koriste okvirne smernice poput "hero character: 30.000-100.000 trouglova" ili "prop objekat: 1.000-10.000 trouglova", ali ovo su samo grube smernice. Sa Nanite sistemom u UE5, ova ograničenja se značajno menjaju jer Nanite automatski prilagođava nivo detalja.

Overdraw

Nije sve u broju trouglova. Veoma mali trouglovi (manji od jednog piksela na ekranu) su problematični jer GPU i dalje troši vreme na njihovu obradu, ali oni praktično ništa ne doprinose vizuelno. Ovo se zove quad overdraw problem — GPU obrađuje piksele u blokovima od 2×2 (quadovi), pa trougao koji pokriva samo jedan piksel i dalje aktivira čitav quad od 4 piksela.

Vertex density

Koliko je ravnomerno raspoređen "budžet" verteksa? Ako imaš mesh sa 50.000 verteksa ali je 40.000 u jednom malom delu, imaš problem — previše detalja tamo gde možda nije potrebno, a premalo drugde.


Level of Detail (LOD) — uvod

LOD koncept je fundamentalan za real-time grafiku: prikazuj detaljniji mesh kad je blizu kamere, a jednostavniji kad je daleko. Čovek ne može da razlikuje detalj na objektu koji je piksel na ekranu, pa nema smisla renderovati 100.000 trouglova za takav objekat.

Diskretni LOD

Tradicionalni pristup: prave se unapred pripremljene verzije mesh-a sa različitim nivoom detalja:

Engine automatski bira koji LOD da prikaže na osnovu udaljenosti od kamere (ili preciznije, na osnovu toga koliko piksela na ekranu mesh zauzima).

Problem: prelaz između LOD-ova može biti vidljiv — objekat "preskoči" od detaljnog ka prostom. Tehnike za ublažavanje ovog problema uključuju cross-fading (kratka animacija prelaza) i dithering.

Nanite — "beskonačni LOD"

Nanite u UE5 suštinski rešava LOD problem na potpuno nov način — umesto diskretnih nivoa, Nanite kontinualno prilagođava nivo detalja na nivou klastera trouglova, ne celog mesh-a. Delovi mesh-a koji su bliže kameri imaju više detalja, a dalji delovi manje — i to se menja glatko, bez vidljivih prelaza. Detaljno o Nanite-u u poglavlju 30.


Mesh formati

Mesh se čuva u raznim formatima, zavisno od konteksta:

Format za modelovanje

Format za razmenu

Format u engine-u

Unreal Engine ne koristi FBX direktno za renderovanje — importovani mesh se konvertuje u UE5 interni format:


Tipovi mesh-eva u UE5

Static Mesh

Static mesh je mesh koji se ne deformiše — njegova geometrija ne menja oblik tokom runtime-a. Može da se pomera, rotira i skalira (transform), ali temena ostaju na istim relativnim pozicijama.

Primeri: zgrade, nameštaj, kamenje, drveće (stablo, ne lišće), oružje, vozila (karoserija), tereni (mada UE5 ima poseban Landscape sistem za terene).

Static mesh je najefikasniji tip mesh-a za renderovanje jer:

Skeletal Mesh

Skeletal mesh je mesh koji se deformiše na osnovu skeleta (armature) — sistema kostiju i zglobova. Koristi se za animirane likove, životinje, i sve što menja oblik.

Svaki vertex skeletal mesh-a je "vezan" za jednu ili više kostiju, sa odgovarajućim weightom (težinom). Kad se kost pomeri (tokom animacije), verteksi koji su vezani za nju se pomeraju srazmerno svom weightu.

Skeletal mesh-evi su skuplji od static mesh-eva jer:

Skinning — proces izračunavanja finalne pozicije verteksa na osnovu poze skeleta — može da se radi na CPU-u ili GPU-u. GPU skinning je brži i koristi se u modernim engine-ima. Formula za skinning (Linear Blend Skinning):

finalPosition = Σ (weight_i × boneMatrix_i × restPosition)

Za svaku kost koja utiče na vertex, pomnoži poziciju u rest pose sa matricom kosti i weighton, pa saberi sve doprinose. Ovo se radi za svaki vertex svaki frejm.

Landscape / Terrain

Unreal Engine ima specijalizovan sistem za terene — Landscape. Umesto regularnog mesh-a, teren se čuva kao heightmap — 2D slika gde svaki piksel predstavlja visinu terena u toj tački.

Prednosti heightmap-a:

Ograničenja:


Collision mesh

Pored vizuelnog mesh-a, objekti obično imaju i collision mesh — pojednostavljenu geometriju koja se koristi za fizičke interakcije (kolizije, detekcija pogotka, itd.).

Collision mesh je uvek jednostavniji od vizuelnog mesh-a — jer fizičke kalkulacije su skupe, i koristiti vizuelni mesh sa 100.000 trouglova za koliziju bi bilo neefikasno.

Tipovi collision geometrije (od najjednostavnije do najkompleksnije):

  1. Bounding sphere — sfera oko objekta. Najefikasnija za proveru, ali netačna za oblike koji nisu blizu sferi.

  2. Axis-Aligned Bounding Box (AABB) — kutija čije su strane paralelne sa osama koordinatnog sistema. Brza za proveru, ali ne rotira sa objektom.

  3. Oriented Bounding Box (OBB) — kutija koja rotira sa objektom. Malo skuplja od AABB ali tačnija.

  4. Capsule — cilindar sa polukuglama na krajevima. Idealna za humanoidne likove (telo).

  5. Convex hull — najmanji konveksni oblik koji obuhvata mesh. Efikasna za fiziku jer convex-convex kolizija je brza.

  6. Decomposed convex — mesh razbijen na više konveksnih delova. Tačnija od jednog convex hull-a, ali skuplja.

  7. Triangle mesh collision — koristi sam vizuelni mesh (ili simplifikovanu verziju) za koliziju. Najtačnija ali najskuplja opcija.

UE5 koristi kombinaciju ovih pristupa. Za proste objekte — automatski generisan convex hull ili primitivne oblike. Za kompleksne objekte (tereni, arhitektura) — triangle mesh collision. Za likove — kapsule ili kombinacija primitivnih oblika.


Bounding volumes — brza provera pre detaljne

Bounding volume je jednostavan oblik koji potpuno obuhvata mesh. Koristi se za brze provere pre nego što se uradi skuplja detaljna provera.

Na primer: da li zrak pogađa objekat? Umesto da proveriš presek zraka sa svakim od 100.000 trouglova, prvo proveriš da li zrak pogađa bounding sphere objekta (jedna operacija). Ako ne pogađa sferu, sigurno ne pogađa ni mesh — preskoči dalje. Ako pogađa sferu, onda radi detaljniju proveru sa trouglovima.

Ovo je princip koji se koristi svuda u grafici i fizici:

AABB (Axis-Aligned Bounding Box) je najčešći bounding volume. Definisan je sa dva ugla — minimum (x, y, z) i maximum (x, y, z). Provera "da li je tačka unutar AABB" je trivijalna — proveri da li je svaka koordinata između min i max.


Vertex deduplication i vertex splitting

Deduplication

Kad importuješ mesh, engine proverava da li postoje identični verteksi — isti u svim atributima (pozicija, normala, UV, boja...). Ako postoje, čuva se samo jedan, i svi trouglovi koji su koristili duplikate sada referenciraju isti vertex.

Splitting

Suprotno od deduplikacije — vertex mora da se "podeli" kad treba da ima različite atribute na različitim stranama:

  1. Hard edge — različite normale na dve strane ivice
  2. UV seam — različite UV koordinate na dve strane seama
  3. Vertex color boundary — različite boje

Svaka od ovih situacija duplira vertex. Mesh sa mnogo hard edges i UV seams ima značajno veći vertex count za GPU nego što modelar vidi u DCC alatu.

Praktični savet: minimiziraj UV seams (poglavlje 4) i hard edges gde je moguće, posebno na detaljnim mesh-evima. Na low-poly modelu sa 500 verteksa, dupliranje nije problem. Na high-poly modelu sa 500.000 verteksa, loš UV layout može da doda 200.000+ dodatnih verteksa.


Proceduralna geometrija

Ne mora svaki mesh da bude ručno napravljen u DCC alatu. Proceduralna geometrija se generiše programski — runtime ili u editoru.

Primeri:

U UE5, Geometry Script plugin omogućava proceduralno generisanje mesh-eva u editoru ili runtime-u. Ovo je moćan alat za kreiranje sadržaja, ali sa performance implikacijama — procedurlano generisana geometrija mora da se uploaduje na GPU, što zahteva vreme i memoriju.


Mesh streaming

U velikim scenama (open world igre), nemoguće je držati sve mesh-eve u memoriji istovremeno. Mesh streaming je sistem koji učitava i otpušta mesh podatke po potrebi — kad se kamera približi, detaljni podaci se učitavaju; kad se udalji, otpuštaju se.

Nanite u UE5 ima sopstveni streaming sistem za geometriju — učitava klastere trouglova na zahtev, na osnovu vidljivosti i udaljenosti od kamere. Ovo omogućava scene sa efektivno neograničenom kompleksnošću — samo vidljivi, potrebni podaci su u memoriji.

Za non-Nanite mesh-eve, UE5 koristi LOD sistem i level streaming za upravljanje geometrijom.


Rezime ključnih pojmova

Pojam Značenje
Mesh 3D model — kolekcija verteksa, edges i faces
Vertex Teme — tačka u 3D prostoru sa atributima (pozicija, normala, UV...)
Edge Ivica — linija između dva verteksa
Face Strana — ravna površina definisana sa 3+ verteksa
Trougao (Triangle) Najjednostavniji poligon, osnovna jedinica GPU renderovanja
Quad Četvorougao — preferirani poligon u modelovanju, konvertuje se u 2 trougla
N-gon Poligon sa 5+ temena — treba izbegavati na zakrivljenim površinama
Topologija Način na koji su verteksi, edges i faces organizovani
Edge flow Kako edges prate konture oblika
Manifold Geometrija koja je "fizički moguća" — svaki edge deli max 2 face-a
Vertex normala Vektor u verteksu koji definiše pravac "gledanja" površine — ključan za osvetljenje
Hard edge Oštra ivica gde verteksi imaju različite normale na svakoj strani
Soft edge Glatka ivica gde verteksi dele normale
Winding order Redosled temena trougla — određuje na koju stranu gleda normala
Back-face culling Preskakanje trouglova okrenutih od kamere
Vertex Buffer GPU memorija koja čuva vertex podatke
Index Buffer GPU memorija koja čuva indekse verteksa za formiranje trouglova
LOD Level of Detail — jednostavniji mesh za udaljene objekte
Skinning Deformacija mesh-a na osnovu skeleta (kosti)
Bounding Volume Jednostavan oblik koji obuhvata mesh za brze provere
AABB Axis-Aligned Bounding Box — kutija paralelna sa osama
Collision Mesh Pojednostavljena geometrija za fizičke interakcije
Static Mesh Mesh koji ne menja oblik — najefikasniji za renderovanje
Skeletal Mesh Mesh koji se deformiše animacijom — koristi skelet i kosti

Sledeće poglavlje se bavi UV mapping-om — kako se 2D teksture preslikavaju na 3D površine. Ako mesh definiše oblik, UV mapping definiše kako se taj oblik "oboji".

📖 Dalje čitanje: