Poglavlje 4: UV Mapping

Poglavlje 4: UV Mapping

U ovom poglavlju učiš kako se 2D teksture preslikavaju na 3D površine. UV mapping je most između geometrije (poglavlje 3) i tekstura (poglavlje 5) — bez njega, 3D model bi bio samo bezličan oblik bez boje, detalja i karaktera. Razumećeš zašto je ovo uopšte problem, kako se rešava, i zašto lightmap UV-ovi imaju posebne zahteve.


Problem: 2D slika na 3D površini

Imaš 3D model — recimo, kutiju. Imaš 2D sliku — recimo, teksturu drveta. Kako da "nalepniš" tu sliku na kutiju?

Ovo je suštinski isti problem kao u kartografiji: Zemlja je sfera (3D), a mapa je ravna (2D). Kako projektovati sfernu površinu na ravan papir? Odgovor: ne postoji savršen način. Svaka projekcija unakazuje nešto — ili se dimenzije iskrivljuju, ili uglovi, ili površine. Merkatorova projekcija čuva uglove ali dramatično uvećava površine blizu polova (zato Grenland na mapi izgleda velik kao Afrika, iako je zapravo 14 puta manji).

UV mapping je isti problem. 3D površina (mesh) se "razvija" na 2D ravan, i ta 2D ravan se koristi kao koordinatni prostor za teksturu.

Najjednostavnija analogija

Zamisli kartonsku kutiju. Kad je sečeš i razviješ na ravno, dobiješ oblik od šest povezanih pravougaonika. Svaka strana kutije je sada na ravnoj površini, i na tu ravnu površinu možeš da nacrtaš bilo šta — grafiku, tekst, boju. Kad ponovo saviješ karton, crtež se pojavljuje na kutiji.

UV mapping je upravo to — "sečeš" 3D mesh duž izabranih ivica (UV seams) i "razvijaš" ga na ravan, gde svaki vertex dobija koordinate u 2D UV prostoru. Tekstura se "crta" na tu ravnu projekciju, i kad se mesh renderuje, GPU čita odgovarajuće delove teksture za svaki piksel.


Šta su UV koordinate?

UV koordinate su 2D koordinate pridružene svakom verteksu mesh-a. Slova U i V predstavljaju horizontalnu i vertikalnu osu 2D teksturnog prostora (koriste se U i V umesto X i Y da ne bi bilo zabune sa 3D koordinatama).

UV prostor je konvencionalno definisan ovako:

Opseg 0-1 odgovara celoj teksturi, bez obzira na njenu rezoluciju. UV koordinata (0.5, 0.5) je centar teksture, bilo da je tekstura 256×256, 1024×1024, ili 4096×4096 piksela.

Kako GPU koristi UV koordinate

Kad GPU rasterizuje trougao (pretvaraja ga u piksele), za svaki piksel interpolira UV koordinate tri temena trougla koristeći baricentrične koordinate (detaljno u poglavlju 9).

Rezultat je UV koordinata za taj piksel — na primer, (0.37, 0.82). GPU onda čita boju teksture na toj koordinati — ovo se zove texture sampling (uzorkovanje teksture).

Ali tekstura ima diskretne piksele (texels), a UV koordinata može da bude bilo gde — ne mora da padne tačno na centar texela. Zato postoji filtriranje — GPU interprilira između susednih texela da dobije glatku boju:


Unwrapping — proces kreiranja UV-ova

UV unwrapping je proces kreiranja UV koordinata za mesh — "razvijanje" 3D površine na 2D ravan. Ovo je kombinacija automatskih algoritama i ručnog rada, zavisno od kvaliteta koji se traži.

UV seams — gde "seći"

Da bi razvio 3D površinu na ravan, moraš da je "presečeš" na nekim ivicama. Te presečene ivice su UV seams.

Svaki seam znači da verteksi na toj ivici moraju da se dupliraju — jer na jednoj strani seama vertex ima jedne UV koordinate, a na drugoj strani druge. Kao što smo videli u poglavlju 3, ovo povećava stvarni vertex count za GPU.

Dobro postavljeni seams:

Loše postavljeni seams:

Projekcioni metodi

Postoji više načina za kreiranje UV-ova:

Planarna projekcija — projektuješ mesh na ravan (kao senka na zid). Dobra za ravne površine (zid, pod), loša za zakrivljene.

Cilindrična projekcija — omotavaš teksturu oko objekta kao etiketa oko konzerve. Dobra za cilindrične oblike (kanta, stablo drveta).

Sferična projekcija — projektuješ teksturu kao Merkatorovu projekciju za sferne oblike.

Box/Cube projekcija — projektuješ sa šest strana (gore, dole, levo, desno, napred, nazad). Svaka strana dobija planarnu projekciju. Automatska, često se koristi za arhitektonske objekte.

Automatski unwrap — algoritam pokušava da minimizuje distorziju i seams. Rezultat je funkcionalan ali često neoptimalan — UV islands su nepravilnih oblika i teški za ručno teksturiranje.

Ručni unwrap — artist postavlja seams i podešava UV layout ručno. Daje najbolje rezultate ali je vremenski zahtevan.

U praksi, većina game asseta koristi kombinaciju — automatski unwrap kao polazna tačka, pa ručno podešavanje problematičnih delova.


UV Islands

Kad "razviješ" mesh, dobiješ jedan ili više odvojenih delova u UV prostoru. Svaki taj deo je UV island (ostrvo).

Zamislite naš primer sa kartonskom kutijom: kad razviješ kutiju, možeš da dobiješ jedan povezan oblik (ako sečeš samo duž nekih ivica) ili šest odvojenih pravougaonika (ako sečeš duž svih ivica). Svaki odvojeni oblik je UV island.

Organizacija UV islands

UV islands treba da budu organizovani u UV prostoru (0-1) tako da:

  1. Ne preklapaju se — osim ako namerno (o čemu uskoro)
  2. Efikiasno koriste prostor — minimalno praznog prostora
  3. Imaju konzistentnu veličinu — svi islands treba da imaju sličnu texel density (gustinu piksela po jedinici površine)
  4. Imaju dovoljno razmaka (padding) — između islands treba da postoji dovoljno prostora da se spreče artefakti

Padding (razmak)

Zašto je razmak između UV islands bitan? Zato što kad GPU uzorkuje teksturu blizu ivice UV island-a, bilinearno filtriranje čita piksele iz susednih texela. Ako je susedni texel deo drugog UV island-a (ili prazan prostor), dobićeš "curenje" boje — artefakt gde se boja jednog dela pojavljuje na ivici drugog.

Ovo je posebno vidljivo sa mip-mapama (poglavlje 5) — na nižim mip nivoima, texeli pokrivaju veću UV oblast, pa je potreban veći padding. Opšta preporuka:

Rezolucija teksture Minimalni padding (pikseli)
256×256 2 px
512×512 4 px
1024×1024 8 px
2048×2048 16 px
4096×4096 32 px

Pravilo palca: padding u pikselima = rezolucija / 128, minimum 2 piksela.

Ali ovaj padding je "izgubljen" prostor — ne nosi korisnu informaciju. Zato prevelik padding smanjuje efektivan prostor za detalj. Balans je ključan.


Texel density — konzistentnost je ključ

Texel density (gustina texela) je broj piksela teksture po jedinici 3D površine. Na primer, 512 piksela po metru (ppm) ili 10.24 piksela po centimetru.

Zašto je konzistentnost bitna?

Zamislite da imate dva objekta jedan pored drugog — zid i pod. Zid ima teksturu 2048×2048 na površini od 4 m², a pod ima istu rezoluciju na 16 m². Zid ima 4× veću texel density od poda. Rezultat: zid izgleda oštro i detaljno, pod izgleda mutno. Razlika je upadljiva i narušava realizam.

U profesionalnom radu, cela scena (ili bar svaka kategorija objekata) treba da ima konzistentnu texel density. Ovo znači da veći objekti dobijaju veće teksture, a manji manje — tako da gustina piksela po metru bude ista.

Kako izračunati texel density?

Texel density = tekstura_pikseli / uv_prostor × (1 / objekat_dimenzija)

Pojednostavljeno: ako je UV island širok 50% UV prostora (0.5), a tekstura je 1024×1024, taj island ima 512 piksela širine. Ako taj island pokriva 2 metra na 3D objektu, texel density je 512 / 2 = 256 piksela po metru.

Alati u DCC softverima i game engine-ima često imaju vizualizaciju texel density-ja — obojeni overlay gde zelena znači ciljanu gustinu, plava premalo, crvena previše.

Ciljane texel density vrednosti

Ne postoji univerzalna "tačna" vrednost — zavisi od ciljane platforme, udaljenosti kamere od objekta, i raspoloživog budžeta za teksture. Ali tipične smernice:

Ključno je da svi objekti u istom vidnom polju imaju sličnu gustinu. Kad kamera prilazi bliže, mip-mape i virtualne teksture upravljaju detaljom — ali bazna texel density mora da bude konzistentna.


Overlapping UVs

Ponekad namerno preklapaš UV islands:

Simeterija

Ako je objekat simetričan (npr. lice), možeš da preklopiš levu i desnu stranu — obe koriste istu teksturu, efektivno dobijajući duplu rezoluciju za istu količinu teksture memorije. Nedostatak: leva i desna strana moraju da izgledaju identično — nema asimetričnih detalja (prljavštine samo na jednoj strani, itd.), osim ako koristiš dodatne maskove ili vertex color.

Ponavljajući elementi

Na objektu sa ponavljajućim detaljima (cigle na zidu, šrafovi na mašini), identični delovi mogu da dele UV prostor. Ovo dramatično štedi memoriju teksture.

Gde overlapping NE sme

Lightmap UV-ovi ne smeju da se preklapaju. Ovo je fundamentalno pravilo i detaljno je objašnjeno u nastavku ovog poglavlja. Razlog: lightmap čuva informaciju o osvetljenju za svaki deo površine. Ako se dva dela preklapaju u lightmap UV-u, dobijaju isti osvetljenje — što je očigledno pogrešno (jedna strana kutije može biti u senci, druga ne).


UV kanali (Multiple UV sets)

Mesh može da ima više UV kanala (UV setova). U UE5, podržano je do 8 UV kanala (UV0 do UV7).

Česte upotrebe:

UV0 — primarni UV kanal za materijal. Teksture boja, normala, roughness-a, itd. se mapiraju kroz ovaj kanal.

UV1 — najčešće se koristi za lightmap UV. Ovo je UV layout gde nijedan island ne sme da se preklapa i svi moraju da budu u opsegu 0-1 (detaljno u sledećoj sekciji).

UV2-UV7 — dodatni kanali za specifične potrebe:

Svaki dodatni UV kanal povećava vertex data — dva float-a (U i V) po verteksu po kanalu. Za UV0 i UV1, to je 8 bajta na podatke svakog verteksa. Nije ogromno, ali se sabira.


Lightmap UV-ovi — poseban slučaj

Lightmap UV-ovi su toliko bitni da zaslužuju posebnu sekciju. Ovo je oblast gde mnogi početnci prave greške, pa ćemo detaljno.

Šta je lightmap?

Lightmap je tekstura koja čuva prebačene (baked) informacije o osvetljenju za statičnu geometriju. Umesto da engine izračunava osvetljenje u realnom vremenu za svaki piksel svaki frejm, osvetljenje se prekalkuliše jednom i "napeče" u teksturu. Ova tekstura se zatim primeni na mesh — svaki piksel mesh-a čita svoju osvetljenost iz lightmape.

Lightmape su i dalje relevantne uprkos dinamičkim sistemima kao Lumen — koriste se za mobilne platforme, za statičnu arhitekturu gde performanse mogu biti problem, i u hibridnim pristupima. Detaljno o lightmapama u poglavlju 24.

Zahtevi za lightmap UV

Lightmap UV mora da zadovolji stroge zahteve:

1. Nema preklapanja (No overlap)

Svaki deo 3D površine mora da ima jedinstvenu poziciju u lightmap UV-u. Ako se dva dela preklapaju, dobijaju isti osvetljenje — lopta u senci i lopta na suncu izgledaju isto. Nema logike.

Ovo je razlika od materijalnog UV-a gde preklapanje može biti namerno (simetrija, ponavljanje).

2. UV-ovi moraju biti u opsegu 0-1

Za lightmape, svi UV islands moraju da budu unutar opsega (0,0) do (1,1). UV-ovi van ovog opsega neće biti ispravno osvetljeni.

(Za regularne materijale, UV-ovi van 0-1 opsega su česti — koriste se za tiling, gde se tekstura ponavlja.)

3. Dovoljan padding

Između lightmap islands mora da postoji dovoljan padding — jer bilinearno filtriranje lightmape može da "prevuče" osvetljenje sa jednog island-a na drugi. Problem je izraženiji nego kod regularnih tekstura jer lightmape obično imaju nisku rezoluciju (64×64, 128×128, 256×256).

4. Minimalna distorzija

Lightmap UV treba da ima minimalnu distorziju — svaki texel lightmape treba da pokriva približno istu količinu 3D površine. Ako je distorzija velika, neki delovi površine dobijaju previše detalja osvetljenja (rasipanje rezolucije), a drugi premalo (vidljivi artefakti).

5. Efikasno korišćenje prostora

Lightmape se generišu za svaki statični mesh instancu u sceni. Ako UV layout loše koristi prostor (mnogo praznog prostora), dobijaš veliku lightmapu za malo korisne informacije — rasipanje memorije.

Automatski vs ručni lightmap UV

UE5 može automatski da generiše lightmap UV iz postojećeg UV0 kanala — razdvaja islands da eliminiše preklapanje i smešta ih u 0-1 prostor. Ovo je zgodno ali često neoptimalno — automatski algoritam ne zna koji delovi su bitniji ili vidljiviji.

Za profesionalnog rada, lightmap UV se obično pravi ručno ili polu-automatski u DCC alatu, sa pažnjom na:

Lightmap resolution

Svaki mesh instance u sceni ima svoju lightmap rezoluciju — koliko piksela lightmape pokriva taj objekat. Veća rezolucija = detaljnije osvetljenje, ali i više memorije i vremena za baking.

Tipične vrednosti:

Lightmap memorija raste kvadratno sa rezolucijom: 256×256 lightmapa je 4× veća od 128×128. Ovo se brzo sabira u scenama sa mnogo objekata.


UDIM — UV izvan 0-1

Problem sa jednim UV prostorom

Standardni UV prostor (0-1) ograničava koliko detalja možeš da imaš. Za hero asset (glavni lik, važan prop), ponekad trebaš veću rezoluciju nego što jedna tekstura razumne veličine može da pruži.

Na primer, za filmskog kvaliteta lice lika, trebaš 8192×8192 ili više piksela. Ali jedna tekstura te veličine zauzima ogromnu količinu memorije (256 MB nekompresovano za RGBA8). Alternativa: koristi više manjih tekstura, svaka za deo modela.

Šta je UDIM?

UDIM (U-DIMension) je konvencija koja proširuje UV prostor izvan 0-1 opsega, deleći ga na "tile-ove":

        V
    3 |  1003 | 1013 | 1023 |
    2 |  1002 | 1012 | 1022 |
    1 |  1001 | 1011 | 1021 |
    0 |       |      |      |
      +-------+------+------+
          0      1      2      U

Svaki tile ima UDIM broj: 1001 + U_offset + V_offset × 10

Svaki tile može da ima svoju teksturu. Na primer, lice lika je na tile 1001, telo na 1002, ruke na 1003 — svaka sa sopstvenom teksturom 4096×4096. Efektivno, imaš 3× više rezolucije nego sa jednom 4096 teksturom.

UDIM u UE5

UE5 podržava UDIM za Virtual Textures. Teksture se importuju sa UDIM konvencijom u imenu fajla (npr. character_basecolor.1001.png, character_basecolor.1002.png), i engine ih automatski kombinuje.

UDIM je standard u filmskoj industriji i high-end produkcijama. Za real-time igre, koristi se uglavnom za hero asset-e gde je kvalitet prioritet.


Tiling teksture

Suprotno od UDIM-a (više prostora za veću rezoluciju), tiling je tehnika gde se ista tekstura ponavlja preko veće površine.

Kad UV koordinate izađu van 0-1 opsega, podrazumevano ponašanje je wrapping — tekstura se ponavlja. UV koordinata 1.5 čita teksturu na 0.5, UV 2.3 čita na 0.3, itd.

Ovo je izuzetno korisno za velike površine sa ponavljajućim materijalom — zid od cigle, travnata površina, asfalt. Umesto ogromne teksture koja pokriva ceo zid, koristiš malu teksturu (npr. 1024×1024) koja se ponavlja koliko god puta treba.

Wrap modes

GPU podržava različite načine ponašanja kad UV izađe van 0-1:

Wrap (Repeat) — tekstura se ponavlja. UV=1.5 → čita na 0.5. Najčešći mod za tiling materijale.

Clamp — UV se ograničava na 0-1. UV=1.5 → čita na 1.0 (ivični pikseli se "razvlače"). Korisno za UI teksture i lightmape.

Mirror — tekstura se ponavlja ali naizmenično ogledalo. UV=1.5 → čita na 0.5, UV=2.5 → čita na 0.5, ali UV od 1.0 do 2.0 je ogledalni prikaz. Korisno za simetrične ponavljajuće uzorke.

Problem tiling-a: vidljivo ponavljanje

Kad koristiš tiling teksturu na velikoj površini, ponavljanje postaje vidljivo — mozak prepoznaje identičan pattern koji se ponavlja. Ovo ubija iluziju realizma.

Rešenja za borbu protiv vidljivog ponavljanja:

O ovim tehnikama detaljno u poglavljima 19 i 20.


UV distorzija — šta je i zašto je bitna

Kad razviješ 3D površinu na ravan, nemoguće je to uraditi bez neke distorzije (osim za već ravne površine). Distorzija znači da su proporcije u UV prostoru različite od proporcija na 3D modelu.

Tipovi distorzije

Stretch (rastezanje) — deo UV-a je rastegnut u jednom pravcu. Tekstura na tom delu izgleda "razvučeno" — jedan pravac ima veću rezoluciju od drugog.

Compression (sabijanje) — deo UV-a je sabijen. Tekstura izgleda stisnuto — detalji su zgužvani.

Area distortion — neki UV islands zauzimaju neproporcionalno velik ili mali deo UV prostora u odnosu na njihovu 3D površinu. Rezultat: nekonzistentna texel density.

Checker map — alat za proveru distorzije

Najjednostavniji način da proveriš UV kvalitet je da primeniš checker map (šahovsku teksturu) na model. Ako su kvadratići checker-a uniformni po celom modelu — UV-ovi su dobri. Ako su negde rastegnuti, sabijeni, ili deformisani — tamo je distorzija.

Svaki DCC alat i UE5 imaju opciju za checker map prikaz. Ovo je jedan od prvih koraka u kontroli kvaliteta UV-ova.


Praktični workflow za UV mapping

Evo tipičnog workflow-a za kreiranje UV-ova game-ready modela:

1. Planiranje seams-ova

Pre nego što počneš unwrap, isplaniraj gde će ići seams:

2. Unwrapping

Postavi seams i izvrši unwrap. Koristi odgovarajuću projekciju za svaki deo:

3. Relax / Straighten

Nakon inicijalnog unwrap-a, UV islands obično imaju distorziju. Koristi relax (opusti) alat koji minimizuje distorziju — algoritam iterativno podešava UV pozicije da budu proporcionalne 3D geometriji. Straighten (ispravi) alatka ispravlja redove verteksa u UV prostoru — korisno za arhitektonske elemente sa pravolinijskim ivicama.

4. Packing

Smesti sve UV islands u 0-1 prostor sa minimalnim neiskorišćenim prostorom. Automatski packing algoritmi rade ovo prilično dobro, ali ponekad ručno podešavanje daje bolje rezultate.

Cilj: maksimizovati iskorišćenost UV prostora (UV coverage). Profesionalni standardi ciljaju 70-85% coverage.

5. Provera

6. Lightmap UV

Ako mesh koristi statičko osvetljenje, kreiraj lightmap UV (obično UV1):


UV mapping za specifične slučajeve

Organski modeli (likovi, bića)

Za organske modele, UV seams treba da prate anatomske granice — linije gde se odeća spaja sa kožom, ispod ruku (axila), iza ušiju, ispod brade. Lice obično dobija veći procenat UV prostora jer je najvidljiviji deo.

Hard-surface modeli (vozila, oružja, mašine)

Hard-surface modeli imaju jasne ivice gde se seams lako kriju. UV islands su obično pravolinijski i lako se pakuju.

Arhitektura

Arhitektonski elementi često koriste tiling teksture umesto uniqueUV-ova. Zidovi, podovi, plafoni — sve koristi ponavljajuću teksturu. UV-ovi su prosti — planarna projekcija skalirana da daje željenu texel density.

Za elemente gde su lightmape potrebne, lightmap UV se i dalje pravi bez preklapanja.

Prirodni elementi (stene, teren, drveće)

Stene i teren često koriste triplanar mapping — tekstura se projektuje sa tri strane (gore, napred, sa strane) i blenduje na osnovu normale površine. Ovo eliminiše potrebu za ručnim UV-ovima i dobro radi za organske, nepravilne oblike.

Drveće koristi kombinaciju: stablo ima cilindrični UV, lišće je obično atlas (mnogo listova u jednoj teksturi), a grane koriste planarnu projekciju ili atlas.


UV artefakti i kako ih rešiti

Seam vidljivost

Problem: na UV seamu, tekstura ima diskontinuitet — susedni pikseli na 3D površini čitaju nesusedne delove teksture. Rezultat: vidljiva linija na modelu.

Rešenja:

Stretching

Problem: rastegnuta tekstura — detalji su izduženi u jednom pravcu.

Rešenja:

Bleeding

Problem: boja jednog UV island-a "curi" na ivice drugog na mip-mapama.

Rešenja:


UV koordinate i shader

U shaderu, UV koordinate su dostupne kao vertex atribut koji se interpolira preko trougla. Shader može da:

UV manipulacija u shaderu je fundamentalna tehnika za mnoge vizuelne efekte:


Rezime ključnih pojmova

Pojam Značenje
UV koordinate 2D koordinate koje mapiraju teksturu na 3D površinu
UV prostor 2D prostor (obično 0-1) gde se UV layout nalazi
UV unwrapping Proces "razvijanja" 3D površine u 2D za teksturiranje
UV seam Ivica gde se mesh "seče" pri razvijanju
UV island Povezan deo mesh-a u UV prostoru
Texel Piksel teksture
Texel density Broj piksela teksture po jedinici 3D površine
Padding Razmak između UV islands za sprečavanje bleeding-a
Overlapping UVs Preklopljeni UV-ovi — za simetriju ili ponavljanje
Lightmap UV Poseban UV kanal bez preklapanja, za baked osvetljenje
UDIM Konvencija za proširenje UV prostora na više tile-ova
Tiling Ponavljanje teksture preko površine
Wrap mode Ponašanje kad UV izađe van 0-1 (Repeat, Clamp, Mirror)
Triplanar mapping Projekcija teksture sa tri strane bez UV-ova
Checker map Šahovska tekstura za vizuelnu proveru UV distorzije
UV channel Jedan od više UV setova na mesh-u (UV0, UV1, itd.)
Distorzija Deformacija UV-a u odnosu na 3D geometriju (stretch, compression)

Sledeće poglavlje ulazi u svet tekstura detaljno — rezolucije, formati kompresije, mip-mape, streaming, i kako engine upravlja teksturama u memoriji.

📖 Dalje čitanje: