HTML

gondolataim elsősorban játékfejlesztésről

Elsősorban játékfejlesztés magyarul: az enginem fejlesztése során felmerülő problémák, ötletek, tévutak stb dokumentálása, amely számomra és talán mások számára is hasznos lehet később Másodsorban gondolatok szavakban...

Kapcsolat:
aalberik 'at' gmail 'dot' com

Haletető

Galéria

Címkék

Összes

Linkblog

Naptár

május 2025
Hét Ked Sze Csü Pén Szo Vas
<<  < Archív
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

to VBO or not to VBO

2010.03.15. 13:46 :: syam

Hála Geri kitartó segítségnyújtásának találtunk egy érdekes hibát az enginemben. Mint az kiderült több helyen is írják, hogy ha a rendereléshez küldött adatok közül egyik nem VBO-zott, akkor semmit sem szabad VBO-zva küldeni. A régebbi kártyák különösen érzékenyek (fps:600 -> 40) erre.

 

Szólj hozzá! · 1 trackback

Demo 5 - csontanim

2010.03.14. 15:45 :: syam

UPDATE!

Frissült a csomag: két exe található a csomagban két különböző fizikai engine-re épülve; egyik PhysX-et használ, a másik Bullet-et.

 

Ismét elérkeztem egy következő állomáshoz. Elmúlt időszakban a csontanimmal foglalkoztam és ez a demó ennek eredményét szeretné bemutatni. Sok próbálkozás után a CPU-n és szálban történő dupla bufferelt VBO nélküli megoldás mellett döntöttem.

Mr. Box (ahogy fpeti nevezte) most már kikerült a főszereplői státuszból helyette a Quake4 berserkerét láthatjuk (néhány részlet lemaradt róla, mert csak az első mesht csatoltam a szereplőhöz). A "pálya" egyik részén vannak a szereplők, a másikon a szokásos "meglepetés": ládák és hordók.

Mozgatás: még mindig a szokásos QWASD + egér, de az egér mozgatáshoz már csillapítás is társul.

Kamera közelítés/távolítás: 3/2 gomb.

Szereplők közötti váltás: TAB.

Ismert hibák: Az animáció messze áll a tökéletestől egyelőre "működik"; nálam néha fagyott (interpolátor túlcsordul):3

A szereplőknek nincs intelligenciájuk csak rohangálnak faltól-falig.

A fizika is csak "van" nincs kiegyensúlyozva.

Az editor fagy.

Config.ini:

vsync_enabled=true / false;
physics_accuracy=3; - fizika iterációk száma framenként
physics_hardwareEnable=false; - nincs hatással
window_depth=24;
window_fullscreen=true;
animation_fps=30; - az animációs szál frissítési frekvenciája - FONTOS! Két mag/CPU esetén ezt fel lehet venni 60-ra egyéb esetben érdemes ezt alacsonyan (30) tartani; jelenleg nincs egyszálas kód.
texture_quality= 2 - 0-low, 1-medium, 2-high, 3-ultra high, 4-oldschool
MODE=1; - jelenleg csak az ablak méretére van hatással ( window_width=800; window_height=600;)
 

Link: www.inspekcio.hu/indigo_illusions/demos/sakura_demo_2010_03_14.zip

 

Szólj hozzá!

Klasszik kopipészt fail

2010.03.13. 17:19 :: syam

Két klasszikus másolás-fáradtan hiba.

_cica* dorombol (_cica* cica)
{
   _cica *new_cica = new _cica;
   new_cica.Új (new_cica);
}

 void Olvas (_cica *cica, _io *io)
{
  cica->Ír (io)
}

Mindkettő után csak pislog az ember, hogy mitől kicsi a buffer avagy miért túl nagy a lefoglalni kívánt terület :3

 

Szólj hozzá!

Dupla szál, dupla buffer

2010.03.11. 15:49 :: syam

Az elmúlt időben sokat foglalkozva a csontváz alapú animálással sokféle optimalizálási lehetőség felmerült. Legtöbbjük csak korlátozottan vagy speciális helyzetekben volt alkalmazható. Utolsó választásom a probléma többszálúsításra esett mivel manapság egyre inkább elterjedtté válnak a két- ill. többmagos cpu-k.

Ha teljesítményfokozásra szeretnénk használni a másik szálat akkor óvatosnak kell lennünk. Előfordulhat ugyanis, hogy a kétszálas megoldás lassabb lehet, mint az eredeti változat. Különösen igaz ez akkor, ha a két szálat szinkronizálnunk kell várakozás beiktatásával vagyis úgy tünik, hogy a szinkronizálás ezen formája teljesítményfokozás céljából mindenképp kerülendő (bár nem ástam magam mélyre a szálazás rejtelmeibe a szinkronizálás másfajta lehetőségeiért).

Azonban viszonylag egyszerűen kiiktathatjuk a várakozás szükségességét, ha a két szál által használt adatot dupla buffereljük. Mint legtöbb esetben ez itt is azt jelenti, hogy az egyik szál az egyik bufferból csak olvas, míg a másik szál a másik bufferbe csak ír. Amikor a másik szál végzett az írással (mivel gyakorta ez a lassabb művelet) akkor a buffereket felcseréljük. Így sosem fordulhat elő, hogy az írás alatt álló buffer kerül olvasásra. Megjegyzendő, hogy a bufferváltás csak egy utasításból állhat! Ellenkező esetben a bufferváltás közben bizonyos ideig ugyanazon buffert használhatja vagy ugyanazt az adatot láthatja a két szál (ezen hiba felismerése majdnem 2 órámba került).

Két gyakorlati alkalmazás az esetemben:

  • a renderelés mindig nem abból a vertex bufferből történik, amelynek a vertexeit számoljuk vagyis a fő szál olvas és az animáló szál ír
  • az animálandó modellek listája is szintén dupla bufferelt, de itt a fő szál ír és az animáló szál olvas

Szólj hozzá!

Címkék: csontváz multithread

Csontanim 2

2010.03.07. 15:38 :: syam

Ismét elérkezett az idő, hogy foglalkozzam a csontanimmal. Szerencsére a formátumom még mindig megállja a helyét, a kódom 90%-ban újrahasznosítható volt tehát a md5mesh/md5anim importáló gyorsan a rendelkezésemre állt.

Első dilemma

Azt mindenki tudja, hogy adott frame-hez tároljuk a csontok térbeli pozícióját és orientációját. Ennek azonban két változata lehetséges: mátrix alapú (későbbiekben M) ill. kvaternió + pozíció (későbbiekben QP) alapú. Az előbbi 12 floatot jelent az utóbbi 7 floatot. Interpoláláskor jelentkeznek a jelentős különbségek: M esetben egyszerű lineárisan interpolálni viszont az eredményt újranormalizálni kell. QP esetben - ami az ajánlott eset is - 3 floatot kell lineárisan interpolálni, a kvaterniót azonban szférikus-lineárisan kell interpolálni (avagy SLERP). A SLERP az első kritikus rész az animációban vagyis érdemes a SLERP implementációjára egy gyors megoldást keresni.

Második dilemma

Második kritikus rész a csont-vertex transzformálás. Ennek központi eleme, amikor adott vertexre alkalmazzuk a rá ható csontok QP-ját. Itt is két módszer lehetséges: közvetlenül a QP-t alkalmazzuk a vertexre vagy előbb a QP-t átalakítjuk mátrixszá. Tapasztalataim szerint az utóbbi a hatékonyabb. Megfigyelhető, hogy általánosságban gyakori az az eset amikor egy vertexre csak egy-kettő-három csont hat. Ezeket az eseteket külön érdemes kezelni, mert ez is sebesség kritikus rész.

Harmadik dilemma

A harmadikus kritikus rész már a rendereléshez tartozik. Tapasztalom szerint a vbo dupla bufferelése az esetek többségében nem kifizetődő - csak akkor mértem sebesség növekedést, ha legalább 4x rendereltem ugyanazt a modellt.

Konklúzió

Célszerű megoldani, hogy az adott animációs fázisban lévő modellt újrahasznosítsuk: rengeteg számolást spórolhatunk valamint nagyobb eséllyel kihasználhatjuk a dupla bufferelt vbo előnyeit is.

 

Szólj hozzá!

Címkék: csontváz

Amikor egy menet nem elég...

2010.02.28. 20:13 :: syam

Sokáig nem gondoltam bele programozóként milyen is volt a 3D programozói világ gyorsítókártyák nélkül/kezdeti gyorsítókártyákkal. Mai szemmel nézve a különböző felületeken megjelenő effektek nem tűnnek bonyolultnak azonban a kezdetek kezdetén ez nem volt annyira egyszerű. Olyan effektekre gondoljunk, amely mellett/alatt még látszik az eredeti szín/diffúz textúra, mint pl. tükröződés, erőtér effekt, villám, decal stb. Gondoljunk bele ezekhez az effektekhez mire is van szükség: két vagy több különböző textúrára, amelyek ugyanazon felületen/modellen jelennek meg. Ennek megvalósítására két lehetőség kínálkozik: az ún. multitextúrázás ill. multipass rendering(többmenetes renderelés). A kezdetek kezdetén azonban még nem létezett az első megoldás így a második lehetőség jöhetett csak számításba. Azonban a multitextúrázás meglétének ellenére még ma is sokszor előfordul, hogy ugyanazon háromszögeket többször jelenítünk meg - ha nem elérhető elegendő textúrázó egység vagy egy különálló (és/vagy speciális) renderelési fázist igényel az adott effekt.

A megvalósítása az alábbiakat igényli.

  • Figyelnünk kell a rajzolási sorrendre ti. ez határozza meg a rétegek egymásra hatását.
  • Be kell kapcsolnunk a polygon offsetet. Erre az ellenkező esetben fellépő z-fight miatt van szükség. Ajánlott glPolygonOffset paraméterek: 0, -100...-600.
  • Ki kell kapcsolnunk a depth bufferbe írást vagyis glDepthMask (GL_FALSE). Erre szintén a z-fight ad okot.
  • Be kell kapcsolnunk az alpha testet és/vagy a blendet.
  • Amennyiben csak alpha testet engedélyezünk, akkor csak egymásra tudjuk a rétegeket maszkolni.
  • Blend esetén a két réteg egymással az elérhető blendelési funkciókkal kombinálható. Multitextúrázás emulálása esetén a GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, decal esetén GL_DST_COLOR, GL_SRC_COLOR a gyakori azonban bármilyen más kombináció is elképzelhető az elérni kívánt hatástól függően (lightmap réteg renderelése esetén GL_DST_COLOR, GL_ZERO kombináció gyakori).

A technika nagy hátránya, hogy

  • ahányszor (ahány réteget) renderelünk, annyiszor küldjük el a geometriát és annyiszor raszterizálunk vagyis csökkenti a teljesítményt- leggyakrabban fill rate területén érezteti a hatását
  • a rétegeket csak az elérhető blendelési funkciókkal tudjuk kombinálni

Megjegyzendő, hogy a hatás megbolondítható a glColorMask funkcióval vagyis ilyenkor bizonyos rétegek adott színcsatornát írhatnak felül.

Természetesen a multipass rendering kifejezést nem csak ilyen esetben használjuk. Gyakran előfordul, hogy egy renderelési fázis eredménye közvetlenül nem jelenik meg a színbufferben pl. offscreen renderelünk vagy stencil bufferbe.

 

Szólj hozzá!

Címkék: decal polygon offset z fight multipass rendering

Shadow map ismét

2010.02.24. 20:27 :: syam

 

Az árnyékvetés elve

Az elv egyszerű. Képzeljük el a fényforrást, mint egy kamera valamint a nézeti sugarakat fénysugarakkal helyettesítjük. Így a kamera közelsíkjában képződő képen a fényforrás által látott tér jelenik meg - a rendereléshez használt vetítést a fényforrás típusa határozza meg. Mivel a renderelés közben a mélység tesztet bekapcsoltuk a kapott végeredmény mélység buffere azt az információt fogja tárolni, hogy a fény terében lévő mely térbeli pontok esnek a fényforráshoz a legközelebb és azok milyen távolságra vannak tőle. Ezt a gondolatmenetet folytatva rájövünk, hogy hogyan is keletkezik ebből árnyék. A jelenetet még egyszer renderelve immáron az eredeti kamerából egy egyszerű összehasonlítással el tudjuk dönteni, hogy egy adott térbeli pont és a fényforrás között elhelyezkedik-e egy másik pont - ha ez a feltétel teljesül akkor az adott térbeli pont árnyékban van. Ehhez az összehasonlításhoz két dologra van szükségünk: az adott pont fényforrástól való távolságára és az előző menetben kapott mélység bufferre, amely szintén a fényforrástól mért távolságot tartalmaz. Ha az adott pont távolsága nagyobb, mint a mélység buffer megfelelő helyéről (lásd később) vett távolság érték, akkor az adott pont árnyékban van.

A renderelés tehát mindenképp két menetben zajlik.

Elsőként a fényforrás által látott teret rendereljük le és a vetítés során felhasznált mátrixokat és mélység buffert eltároljuk.

 

Második menetben a vertex feldolgozáskor két vertex transzformációt hajtunk végre (ne felejtsük, hogy a vetítés, amely egy a transzformációk közül mindössze vertexek és mátrixok összeszorzását jelenti):

  • vetítünk a kamera nézetéből .Ennek eredménye lesz végül a látható kép.
  • vetítünk a fényforrás nézetéből; ehhez használjuk fel az első menetben eltárolt mátrixokat. Az így kapott transzformált vertexek pedig az előzőleg eltárolt mélység buffer megfelelő helyére fognak mutatni (vagyis oda, ahova a vertex a fényforrásból nézve vetül/vetült) így ezek textúra koordináták használhatók. Fontos megjegyezni, hogy a vetítés eredményeként a vertexek egy (-1,-1,-1)-(1,1,1) kockába kerülnek át így még egy transzformáció szükséges, amely (0,0,0)-(1,1,1) kockába visz át - a textúra tér (0,0)-(1,1) közötti tartományban értelmezett, a mélység pedig (0)-(1) tartományban. Ezt a másodlagos vetítést, az így kapott vertexek textúra koordinátaként való felhasználását és a textúra koordinátákon elvégzett homogén osztást nevezzük projektív texturázásnak.

 

A vetítések során kiszámolt Z koordináta (ha textúra koordinátában gondolkozunk akkor Z komponens helyett R komponens elnevezés az elterjedt) tartalmazza egyik esetben a kamerától való távolságot másik esetben pedig a fényforrástól való távolságot. Végül nincs más dolgunk csak a mintavételezés a mélység bufferből, a két távolságot összehasonlítani és ezt felhasználni a renderelésben.

 

Árnyékvetés texture environment combinerrel

Ez az árnyékvetés számos hátránnyal rendelkezik.

  • A mélység buffert nem tudjuk felhasználni, hanem nekünk kell egy színcsatornába renderelnünk a távolságot.
  • Igen pontatlan a mélységi felbontása mivel a belső feldolgozás során mindenképp 8 bites lesz az általunk számolt távolságérték - annak ellenére, hogy létezik 16 bites színcsatornát támogató textúra formátum.
  • Szükségünk van még egy (egydimenziós) textúrára a távolságméréshez - annak ellenére, hogy a Z koordináta tartalmazza a távolságot.
  • Az összehasonlítást nekünk kell elvégeznünk.

Árnyékvetés natív hardverrel

Szerencsére ez a megoldás az előző árnyékvetés összes hátrányát kiküszöböli.

  • Külön textúra típust biztosít a mélység buffer közvetlen másolásához/tárolásához.
  • Általunk választható precizitás - 16, 24 vagy 32 bit.
  • Nincs szükség textúrára a távolságméréshez, a Z komponens közvetlenül használható.
  • A TMU képes összehasonlítást végezni egy mintavételező regiszter Z kompononse és a mintavételezett érték között; így a mintavételezés eredménye nem az érték lesz, hanem egy boolean (0 vagy 1) érték.

Az OpenGL szempontjából nézve ez az alábbi extension-öket jelenti.

  • GL_ARB_depth_texture: ez teszi lehetővé, hogy az adott textúra a négy komponenst nem négy GL_UNSIGNED_BYTE-ként fogja felhasználni, hanem egy GL_UNSIGNED_SHORT ill. GL_UNSIGNED_INT-ként.
  • GL_EXT_shadow_funcs ill. GL_ARB_shadow: ez teszi lehetővé, hogy a mélységi összehasonlítás be-/kikapcsolható legyen.

Szólj hozzá!

Címkék: tmu shadow map projektiv textura

UltraShadow 1 és 2

2010.02.24. 19:12 :: syam

Mindkét technológiát az NVidia fejlesztette ki.

Az első változat ("mélységi teszt") a scissor teszthez hasonlóan működik viszont nem képernyőkoordinátákra, hanem mélység komponensre értelmezi a vágást: megadott zmin és zmax értékeken belül engedi át a fragmenteket. OpenGL alatt GL_EXT_depth_bounds_test / GL_NV_depth_bounds_test néven elérhető.

A második változat ("kétoldalas stencil teszt") a stencil tesztet gyorsítja fel - külön-külön megadható a stencil beállítás a GL_FRONT és GL_BACK orientációjú poligonokra vagyis stencilezéssel történő CSG műveletek egy lépésben elvégezhetők. Azonban fontos tudni, hogy a renderelés közben a fragmenteket duplázza a GPU így csak a vertexek többszöri elküldését váltja ki. Kötelező együtt használni a GL_EXT_stencil_wrap-pel mivel összetett CSG eljárásnál könnyen alulcsordulhatnak a stencil értékek. Az ehhez tartozó OpenGL extension sztring: GL_EXT_stencil_two_side.
Megjegyzendő, hogy hasonló képességet az ATI is kifejlesztett (GL_ATI_separate_stencil néven) azzal a különbséggel, hogy nem az összes stencil beállítás konfigurálható orientációnként. Az újabb ATI kártyák azonban már az EXT verziót is támogatják.

Szólj hozzá!

Címkék: ultra shadow 1 2

Demo 4

2010.02.07. 12:51 :: syam

Ismét eltelt egy hét és ismét egy lépéssel közelebb a cél felé.

Az alábbi demó egy "valódi" helyszínt tartalmaz, két "főszereplővel" alias ládával, amelyek között "tab"-bal lehet választani.  A "p" billentyű lenyomásával az újonnan implementált hullámfüggvények (eredménye) lesznek láthatók. A mozgás QWASD + egér.

A pályáról kirepülni nem tanácsos...

A renderelés most FPP-n keresztül történik tehát elvileg régebbi kártyákon is futtatható.

Sajnos a portál rendszer működése még nem tökéletes, de vizuális hibákat nálam nem okozott ellenben stack overflow-t igen. Ezen eset lekezelése során "potentially portal overflow" figyelmeztetés jelenik meg a konzolon.

A zip file elérhető innen: www.inspekcio.hu/indigo_illusions/demos/sakura_demo_2010_02_07.zip

Szólj hozzá!

Ismét Quake4

2010.02.04. 09:55 :: syam

Az esti órákban ismét tettem egy felfedezést. Az eddig is nyilvánvaló volt, hogy a Doom3/Quake4 engine portálokkal dolgozik az viszont kevésbé, hogy a .proc file-okból ezen információkat egyértelműen ki lehet nyerni.

Szerencsémre az ottani adatok teljes egészében felhasználhatók minimális konverzióval és kiegészítéssel az enginemben. Remélhetőleg a konverter elkészítése sikerrel jár és ez akkor jelentős mértékben megkönnyíti a tartalom készítést a további következményekről nem is beszélve... ^^

Ráadás, hogy kb. 20 perc alatt elkészült a szöveg parser és még kb. 10 perc volt az adatok beolvasása.

Megjegyzés: a Doom3 .proc file-ok egyszerűbb felépítésűek így a Quake4 .proc file-ok kicsivel más feldolgozást igényelnek.

Szólj hozzá!

Címkék: quake4

süti beállítások módosítása
Mobil