A csúcsérték magasabb a motorban, mint a 3D-s szoftverekben

Miután 3D hálót importált egy olyan szoftverből, mint a Blender, a Maya vagy a Max, a Unity vagy az Unreal Engine programban, rájöhet, hogy a motorban lévő csúcsok száma magasabb, mint a 3D szoftverben látható csúcsok száma. / p>

Nemrégiben bemutatót írtam, ahol csúcsonként számítási árnyalatot futtattam r . Észrevettem, hogy a Blenderben lévő csúcsok száma sokkal kevesebb volt, mint amennyit a Unity mutatott nekem. Azt hittem, hogy a háló sima árnyékolásával történő exportálása megoldja ezt, de kiderült, hogy vannak itt olyan dolgok, amelyeket soha nem vettem figyelembe. Ennek kutatása szétszórt válaszokat adott nekem a különböző fórumokon, ezért úgy döntöttem, hogy megírom ezt a bejegyzést, és tisztázom, miért történik ez. Ez rendkívül nyilvánvaló a legtöbb ember számára, akik ezt a munkahelyen tanulták, vagy elgondolkodtak egy kis időt, de ha nincs melletted tapasztalt mentor, meglepően nehéz teljes választ találni erre az egyszerű kérdésre.

Mi a csúcs

A probléma megértéséhez fontos megérteni, hogy mi is a csúcs. A csúcsokat gyakran összetévesztik pozíciókkal. A csúcs nem pozíció. A pozíció egy csúcs attribútuma. Ebben is bűnös voltam, és természetesnek tartom, hogy összetévesztem, mivel a geometriában a csúcs egy olyan pont, ahol két vonal találkozik. És egy pont magában foglalja a pozíciót.

A számítógépes grafikában ez a meghatározás valami általánosabbra vált. A csúcs egy adattároló, az attribútumok csoportosított sorozata, amelyen egy csúcs árnyékoló dolgozik. Hasonló módon, ahogy az árnyékoló kifejezés az árnyékoló programról a grafikus kártyán futó programra változott, a csúcsokat mindenféle kreatív módon használták az általános számításhoz, még a számító árnyékolók ideje előtt. Tehát lehet, hogy látott egy csúcsot pozícióattribútum nélkül.

A fenti bekezdés azonban kissé érintő, mivel a játékokban és a játékmotorokban egy csúcsnak szinte mindig van legalább pozíciója. Továbbra is fontos a csúcspontok és a csúcsok elkülönítése, mivel két csúcs ugyanolyan helyzetben lehet, de mégis különböző csúcsok lehetnek, mivel különböznek a többi csúcsattribútumukban, például normálban vagy UV-ben.

Az a stat, amelyet a motor vagy a 3D szoftver csúcsok számaként jeleníthet meg, különböző mutatókra hivatkozik. Mielőtt áttekintenénk ezeket a különböző nézőpontokat, és megbeszélnénk, hogy a csúcsok száma mit jelent minden esetben, még egy fontos meghatározást kell áttekintenünk.

Mi az indexpuffer

Ami a háromszögeit illeti, egy csúcsra van szükségük a háromszög minden sarkához. Tehát egy olyan hálónak, amely háromszögek esetén N számmal rendelkezik, N * 3 csúcsra lesz szüksége. Ha több háromszög ugyanazt a csúcsot osztja meg, akkor nincs ok arra, hogy ezt a csúcsot többször is elmentse a memóriába. Ezért találtak ki index puffereket az emberek.

Ahelyett, hogy a grafikus folyamatot 3 csúcscsomaggal látnánk el, 3 indexet (azonosítót) biztosítunk, amelyek arra utalnak, hogy ezek a csúcsok hová lettek elmentve egy tömbben, ahol a memóriában, egy csúcspufferben. A háromszögek csúcsainak indexeit tartalmazó tömböt indexpuffernek nevezzük.

Így elkerülhetővé vált a megosztott csúcsok duplikálása a memóriában, egy extra indexpuffer árán. Ez egy érdemes kompromisszum, mivel a hálónknak kevesebb, mint 65 536 csúcsa van, 16 bites egész számokat használhatunk index pufferünkhöz. Például egy 20k csúcsú hálónak 0,04 MB általános költsége lenne az indexpufferhez. Másrészt, ha ennek a hálónak sok megosztott csúcsa van, és minden csúcs hatalmas, más néven sok nagy pontosságú attribútum, akkor sokkal többet spórolnánk a térben.

Most, hogy megállapítottuk, mi az indexpuffer, nézzük meg, hány csúcsra van szüksége a grafikus API-nak egy olyan háló esetében, amelyen N háromszög található.

Grafikus API-oldal

Ami az API-t illeti, három csúcs árnyékolót kell futtatnia háromszögenként (nem egészen, erre egy kicsit ráérek). Amint fentebb említettük, egy háromszögnek meg kell adnia a 3 csúcsát, hogy meg lehessen rajzolni, megosztani vagy sem. Tehát a motoroknak másképp kell elkészíteniük az adatokat a futási idő használatához, mint ahogyan sorosíthatják őket. A Graphic API által tőlük megkövetelt formátum miatt.

Ha 10 ezer háromszög van a hálón, akkor 30 000-szer kell futtatnia a programot. Mint fentebb említettük, ez nem teljesen igaz. Van egy gyorsítótár-rendszer, amely lehetővé teszi egy csúcs-árnyékoló átugrását, ha már futott egy csúcs-árnyékolót egy csúcson ugyanazzal a bemenettel, amely jelenleg ebben a gyorsítótárban van mentve. A gyorsítótár mérete hardverenként változik, és különböző módon lehet optimalizálni. Nem tudom, hogy az illesztőprogram hogyan dönti el, hogy mely csúcsokat kell megtartani a gyorsítótárban, és mikor kell átkapcsolni egy másik csúccsal. Összefoglalva: az illesztőprogram emlékszik néhány csúcsra, amelyet átalakított a vertex shaderben, és ha pontosan ugyanazzal a bemenettel akarja futtatni a vertex programot, akkor az előző futtatások eredményét használja ahelyett, hogy újra futtatná a vertex shader.

Tehát a vertex shader száma kevesebb lehet, mint a háromszorosok száma háromszorosa, de több, mint amit a 3D-s szoftverében lát.

a motor oldala

Amikor a motor hálót importál, akkor azt úgy kell elkészítenie, hogy a Graphic API képes legyen megjeleníteni. Előfordulhat, hogy a motorok más formátumban is elkészítik a hálózatot véglegesen a merevlemezen, erről a következő részben olvashat.

A preferált formátum az index + csúcspuffer a legtöbb esetben. Tehát hány csúcsot fog látni a csúcspufferben? Esetemben a csúcspufferem 23k csúcsot tartalmazott, míg a Blender 16k csúcsot mutatott. Ennek szabályai egyszerűek, ahhoz, hogy egy csúcsot valóban megosztottnak lehessen tekinteni, minden attribútumának pontosan meg kell egyeznie. Ez nemcsak azt jelenti, hogy ugyanaz az álláspontjuk, hanem normálokat, érintőket, UV-ket stb.

is

A Normals egyszerű. Ha kemény élek vannak osztott normálokkal és különböző simítási csoportokkal, akkor megnő a csúcsszám a motor oldalán, mivel a különböző arcok között megosztott csúcspontok eltérő normálokkal rendelkeznek. Az optimalizáláshoz olyan dolgokat tehet, mint a sima árnyékolás, ahol a normális csúcsot átlagolják az összes arcon, amely megosztja azt, és részletes normál térképekkel rekonstruálja a kemény éleket.

Az UV-fények kicsit trükkösebbek. Ugyanazon helyzetben lévő két csúcsnak, amelyek különböző arcokhoz tartoznak, nem lesz ugyanaz az UV, ha ezek az arcok különböző szigeteken vannak. Tehát, ha optimalizálni szeretné a csúcspuffer számát az UV oldalakon, optimalizálnia kell a kicsomagolást. Pontosabban, kevesebb szigetre kell optimalizálnia.

Más attribútumok, például a Vertex Color vagy bármi más esetében hasonló trükkök használhatók, mint például a normál térképek. Az információkat textúrában sütni. Van egy fordulópont, ahol ezeknek az információknak a textúrából történő olvasása késleltetése magasabb lehet, mint bármi más, amire optimalizál. Ezért mindig érdemes összehasonlítania, hogy valóban optimalizálja-e, vagy rontja-e a helyzetet.

A háló formátumú oldalak

Az, hogy az FBX és az Obj formátumok miként tárolnak hálót, más prioritásokon alapul, összehasonlítva azzal, hogy a motor hogyan pakolja ki őket a RAM-ra. Néhány példa a fájlméret, a betöltési / dekódolási idő, a dekóder és a kódoló egyszerű programozása és az emberek számára olvasható.

A fentiek szerint az extra indexpuffer kompromisszuma jó. Tehát miért ne tenné meg egy lépéssel tovább, és index-pufferrel rendelkezik attribútumonként. Minden csúcshoz több indexet mentene egy helyett. Minden index különböző attribútumok helyére mutat, egy a pozícióra, egy az UV-fényre stb.

Ennek az az előnye, hogy csökkentheti a fájl duplikációját. Képzeljen el egy olyan forgatókönyvet, ahol a Vertex szín többnyire fekete, kivéve néhány példányt, azonban mivel más attribútumok, például a pozíció, a normálok vagy az uv-k nem azonosak, ezeket a csúcsokat nem lehet egyesíteni egy csúcsban, ha csak egy indexünk van puffer. De ha attribútumonként indexpuffer van, akkor elkerülheti ugyanazon Vertex szín mindenhol történő másolását, és csak annyi csúcsszínt menthet el, ahány változat van.

További előnye, hogy ezeket a listákat másként tömörítheti. Érdemes az egyik attribútumot jobban tömöríteni, mint a másikat, különböző algoritmusok használatával.

3D szoftveroldal

Végül eljutottunk a 3D szoftver oldalára, és arra az okra, amiért a Blender sokkal kevesebb csúcsot mutatott, mint a Unity.

Egy 3D-s szoftver megközelítheti ezt, ahogy akarja. Használhatja a fenti módszerek bármelyikét, vagy akár más dolgokat is, például a négyszögeket a háromszögek helyett a csúcsszám csökkentésére. Mire eljut a renderelésig, hasonló korlátozásokkal kell szembenéznie, mint egy játékmotorral.

Előnyei vannak egy 3D-s szerkesztő szoftvernek, ha valami hasonlót csinál, mint ahogy az OBJ formátumok mentik a hálót. Például, ha egy csúcsot mozgat a Blenderben, akkor nem változtatja meg annak normális értékét vagy UV-jét. Csak a csúcs helyzete. Egy kockának 8 sarka van. Ha minden sarok csak egy pozícióból áll, akkor a csúcspufferében 8 csúcs található. Tegyük fel, hogy elmozdítja az egyik sarkot. Az alkalmazásnak mozgatnia kell azt az egyetlen csúcsot.

Most a legostobább módon bontjuk ki ezt a háromszög alakú kockát, minden háromszög a saját szigetévé válik. Ha elmentjük a hálót a motorban, akkor a csúcspufferünk 8 csúcsról 36-ra megy. Összesen 12 háromszög, háromszögenként 3 csúcs, mindegyiknek megvan a maga UV-értéke. Ha most egy sarkot mozgatunk, attól függően, hogy melyik sarokról van szó, a programnak maximum 6 csúcsot kell mozgatnia. Ez a 6 csúcs, amelyek osztoznak egy pozícióban, de eltérő UV-fényük van.

Ha attribútumunkonként indexpufferrel rendelkeznénk, akkor visszatérhet ahhoz, hogy csak egy példányt kell szerkesztenie. Ha csak a pozíciókat mozgatja, és nem tesz semmit az UV-vel, akkor csak egyszer szerkesztheti a 8 csúcs között megosztott csúcspozíciót.

A másik további előny, hogy a memóriamegtakarítást több index-pufferrel lehet megtakarítani, amint azt a Mesh formátumok rész tartalmazza.

Tehát, ha a Blenderben olyan statokat lát, mint a 16k csúcsok, annak inkább valami 16k csúcspozíció mentén kell lennie. Ha tudni akarja, hogy ez a helyzet, próbálkozzon másképp a háló kibontásával. Ha ez nem változtatja meg a csúcsok számát, a mutató valószínűleg a csúcspozíció pufferben lévő tagok számára utal. Ügyeljen arra is, hogy a háromszög alakú hálót nézze, és ne a négyeset.

Köszönöm, hogy elolvastad, követhetsz a Twitteremen: IRCSS