_fpeti_ 2011.03.16. 23:07

Grafikai ráncfelvarrás (nomnoming yo' framerate)

’Deferred is preferred’ tartja a népi bölcsesség.
Ez egy speckó renderelési módszer, a fényeket és árnyékokat utólag adja a látható képhez. Sok problémát meg lehet vele oldani, de sokkal lassabb, főleg egy régebbi dx9-es videókártyán. A régi módszer (forward rendering) 60-100 fps körül ment, ez az új 30 alá is mehet, attól függően, mennyi nagy fényforrás látható éppen. Mondjuk a 7300gs (64 bit) karim nem a legújabb, igazából a geforce 7-es szériájának teteje és azon felülire módosulhat ezzel a becélzott végfelhasználói csoport. Megtartottam a régi, egyszerűesített rajzolást is, csak ott egy fény van csak egyelőre, a nap, azon még dolgozni kéne, hogy így nézzen ki, de az a jövő zenéje. Annyit gyorsítottam a dolgon, hogy a napot egyből a g-buffer generáláskor kiszámolom egy negyedik bufferbe - első a szín, második a normálisok és csillivill-faktor, harmadik a z buffer. Ezzel spórolok egy full-screen-es directional-light rajzolást, ami talán megéri. Fényeket is hozzá lehet kötni tárgyakhoz, így jöhettek létre a himbálózó fények, amik nagyon fontosak, mert anélkül semmik vagyunk. (mondom én, aki 2 órát Minecraft-ol napi szinten :D)

Amúgy van diffúz point és spotlight, valamint textúrás-projekciós spotlight is, mert nem lehet játék rácsos textúrás HIMBÁLÓZÓ spotlight-ok nélkül. A vicces az, hogy a valóságban egy berácsozott lámpa fényében sosem lehet látni a rácsozatot, de ez nem valóság.
Csináltam vizet is, ritka hitvány egy valami lett, el is döntöttem, hogy lehet nem is foto realisztikus megjelenítés lesz. Mondjuk még egy fénytörés/visszaverődés félét csinálok rá (stalker doksi alapján: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch19.html)

Csak még megjegyzem, hogy már a hang része is nagyjából készen van a játéknak, a szokásos wav fileok a 3d-s hangoknak, és .ogg a streamelt muzsikának. Én annyival még megfejeltem a dolgot, hogy a vorbisdll nem a hdd-ről nyomja a zenét, hanem betöltöttem az egész ogg filet ram-ba (3 megát kibírunk), és onnan megy. Hosszabb dialógusokat is lehetne .ogg-ban tárolni, csak nem nagyon akarok dialógusokat, hanem önfeledt szórakozást inkább, a többieknek meg ott a Kossuth Rádió. J

Apropó dialógusok, a ’szkriptrendszert’ is elkezdtem. A törzse már megvan, a legegyszerűbb módot választottam, amit windows-on lehet: minden pályának van egy dll-je, amiben van egy csomó függvény, amit az engine hívogathat, ha valami speciális történik. Pl a pályaszerkesztőben el lehet helyezni 3d-s dobozokat, aminek lehet egy neve. Ha a játékos belép ebbe a dobozba, a pályához betöltött dll-ből meghívja az azonos nevű függvényt. Az a függvény meg tehet, amit akar, leginkább döntéshozó- játéklogikai kódokat tartalmaz. A dll induláskor kap egy nagy struktúrát, amiben az összes olyan függvény pointere megvan, amin keresztül az engine-t elérheti. Első függvény volt, hogy lejátszhat egy hangot, ha a játékos bemegy a dobozba. Miért nem használok lua/python/as cumókat? Nem a sebesség miatt, hanem mert nincs rá szükség. Nincsenek illúzióim a játékkal kapcsolatban, nem lesz külön ember a szkriptelésre, én fogom azt is csinálni.

Itt a szokásos zagyva videó (hangja nincs.)

 

 

 

Címkék:grafika deferred Szólj hozzá!

_fpeti_ 2011.01.27. 01:34

Kelj fel!

 

Ez szerintem vicces. :p

 

Szólj hozzá!

_fpeti_ 2011.01.25. 01:35

Szörnyek alaplángon

Igen, már amennyire egy zöld kocka félelmetes lehet. :) npc-kel foglalkozom manapság, nagyon új, és közepesen érdekes téma. A zöld valamik helyére egy lebegő rémet kellene képzelni, ami szabálytalan lufiszerű mozgással ide-oda libbenve lövöldöz, most még egyelőre egy szimpla részecskét. Elég sokat szívtam a kvaterniós orientációval, nehéz volt pl. megcsinálni, hogy ne fejjel lefele legyen állandóan, hanem forduljon a hasára,ha csak tud. Eddig az van, hogy alapból nézelődik, ha észreveszi az alap-ellenséget (meg lehet adni a látószöget neki), akkor irányba fordul és elkezdi eregetni a golyóit, XD és közeledni. Ha elég közel van, körözni kezd az ellenfele körül, és próbál vízszintes irányba kerülni a célpontjához képest.
Npc-knél az első dolog, ami nálam kötelező, hogy ne csak a játékost támadják, hanem egymást is. Ilyet a doom2-ben láttam először, azóta nagyon tetszik. Egyszerű megoldani, és látványos tömegjeleneteket lehet ezzel elérni. Itt is úgy van, hogy egy npc eltalál egy másikat, akkor az automatikusan visszatámad. Ez addig folyik, míg egyik el nem patkol – pontosabban még tovább is, addig, amíg a halott npc ragdoll-ja is be nem szerez annyi sérülést, hogy lefut a desintegrate() függvénye, ami kitörli a játékból (ide kell majd egy gib-rendszer). Ekkor a győztes npc visszaáll alaphelyzetbe, azaz újra a játékosnak esik. Szerintem nagyon mókás összeveszejteni egy csomó szörnyet, hadd csépeljék agyon egymást.
 

 Elkezdtem a golyónyom megjelenítőn is ügyködni, még elég hiányos. Kétféle van:
egyszerű testekre csak szimpla textúrázott négyszögeket rajzol, mozgó test esetén mozgatja a testtel együtt.
A második decal-féle pedig terrain-ra van, amik robbanásból kifolyólag kerülhetnek a talajra, általában egy kráter aljára.
Mindkettőnél a haladás egyik gátja az, hogy vágni kellene a decaleket, ne lógjanak le a testről. Például ha egy doboz legszélét találjuk el, akkor a golyónyom 4zetből le kell vágni a kiálló részt. Ez nagyon változatos poligonokat eredményezhet, ráadásul, ha a decal alatti terület nem sík, minden egyes 3szögre rá kellene vetíteni a megfelelő részt. Igazából elég sok módját el tudnám képzelni a decal-ek képzésének és rajzolásának, pl vágások helyett deferred shadinggel el lehetne játszani, hogy a fényekhez hasonlóan screen-space-ben a z bufferrel oldanánk meg az egészet. (ha az nem gond, hogy egy dobozról lelógó részlet láthatóvá válik, ha közel kerül egy másik tárgyhoz – jah, ’decal bleeding’)
A terrainra egy trükköt találtam ki, hogy ne kelljen mindig vagdosni:
csak egy méretű decal lehet, az pedig csak a terrainháló csúcspontjaira, vagy éleire eshet. Így 9 esettel meg lehet oldani az összes kombinációt. Ha nem pont csúcsra vagy élre esik a  középpontja, kicsit odébb kell húzni, és már jó is. ;)

 A harmadik jóság, hogy nekiálltam az aljnövényzetnek, mert az is kell (ahhoz volt kedvem – indie dev for de win!!) Úgy csináltam meg, hogy minden talaj textúrához tartozhat egyféle fű textúra, mivel 4 textúra lehet egy talajon, így 4 fűféle kell, amit egy textúrába tettem, így az összes füvet ki lehet rajzolni egyszerre. A fű mesh modelje két négyzet merőlegesen, és ezt rajzolom ki hw instancing-gal. Nem túl nagy területet füvesítek be egyszerre, de így is 400-600 füvet kell alapból kirajzolni, ami nekem soknak tűnik, főleg ahhoz képest, ahogy kinéz. Mondjuk olyan sok fps-t nem vesz le. Még csak félig van kész, a távoli fűvek eltűnését alpha-dissolve módszerrel fogom finomítani, a frustum culling se tökély. Amúgy a generálása per terrain-háromszög történik, és raktározza addig, amíg az a 3szög látszik, vagy elég távolra nem kerül. Fontos, hogyha megváltozik a terrain (pl bombázás – esetleg creepers, Minecraft rulez amúgy ,) ), akkor a rajta lévő füvek pozíciója is idomuljon, ne lebegjenek a föld fölött.

 

Szólj hozzá!

_fpeti_ 2010.11.05. 05:12

Dekorációk a játékban.

Mostanában egy lenge növényzettel és egyéb fizikával nem rendelkező objektumokkal foglalkoztam. A Havok alapjáraton 16K rigidbody-t enged egyszerre a szimulációba, ami a 16 biten tárolt értékek miatt van. Át lehet kapcsolni 32 bitre is, ami már 4giga objektum, de semmi értelme ennyivel kezdeni, és felére lassul az axissweep-teszt dupla memóriaigénye miatt. Egyébként sem ildomos minden fűt-bokrot fizikailag leképezni, csak akadályozna a mozgásban. Ez a (CDecor) osztály tehát nem tud mást, mint tartalmaz egy mesh-t, amit kirajzolhatunk, más játékra gyakorolt hatása nincsen. Fura is volt ezt csinálni, mert az elmúlt kb 1 évben csak a legfontosabb elemekkel, a játékmotor nyers mechanikájának összebarkácsolásával foglalkoztam (egy lépés előre, kettő oldalra formában). Mondjuk a framerate-re igen szép hatással tud lenni – hw instancing már nem késhet soká.
A jópofa ezekben a nagyrészt statikus dekorációkban az, hogy bevezettem egy ’parenting’  (szülő-gyerek) rendszert a játékbeli objektumok között, amivel össze lehet őket kapcsolni, amennyit a ’szülő’ elmozdul, annyit mozog a ’gyerek’ is. Ez egyébként is bevett dolog játékmotorokban. A videó elején látható, hogy a pálmát megütve a rácsatlakozott ’fagyöngyök’ együtt mozognak a levéllel, vagy az ellőtt fa kidőlő részével együtt mozog a lombja. A csatlakozásokat a pályaszerkesztőben kell kijelölni, majd töltéskor a játék megkeresi (összetett fizikai objektumok estén) a legközelebbi rigidbody-t (itt a pálma-model esetén a megfelelő levelet). Eltárolja a relatív transzformációt, majd bejegyzi a szülőnek, hogy van gyereke. Ezután ha a szülő elmozdul, értesíti a gyereket, aki frissíti a mátrixát. A kapcsolati rendszer fix tömbökkel történik, minden objektumnak max 8 gyereke lehet (egyéb ízületekkel együtt). Ha a szülő törhető, mint az kettérobbantott/lőtt fák, akkor törésnél meg kell keresni azt a darabot, amelyikhez a legközelebb van, és arra újra rá kell csatlakoztatni. Vagy törölni, ha nem maradt semmi. (esetleg széjjelfagy – ez is opció volt egy darabig ;))

 

Címkék:dekoráció Szólj hozzá!

_fpeti_ 2010.10.15. 05:55

Kevés haladás, kis videó.

Hát igen, a Fraps 30 másodprecet enged 'ingyér' egyszerre. A lényeg, hogy nagyjából látszik, hogy működőképes az animáció, és a halálozás utáni ragoll is működik.

Próbáltam több fegyót is használni, az nagy fehér cső egy rakétavető, csak nem volt a tárban egy raksi sem, elfelejtettem felvenni lőszert hozzá. :) De volt pisztoly, egy vérbénán kinéző puskaféle, valamint személyes kedvencem, a kézigránát, amit az utolsó utáni másodpercben vetettem be.

 

Szólj hozzá!

_fpeti_ 2010.10.12. 03:51

Egy kis videó

Nagy éjszaka ez a tegnapi/mai, mert sikerült nagyjából kiépíteni a sérülés-rendszert a játékban. Na nem kell bonyolult dolgokra gondolni, csak annyi az egész, hogy ha egy npc találatot kap, vagy közelében robbanásra kerül sor, meg is sérül.Ami nem változott, hogy minden borzalmasan néz ki; ilyen ha valaki Blenderrel és semmi tudással, 3 perc alatt (nem) akar valamit alkotni – és nem sikerül. ;) A szerencsétlen NPC, kinek kódneve ’SonofaPeach’, még mindig elég butus, csak annyit tud, hogy jön a játékos felé, és ha odaért, akkor nem csinál semmit.
Kicsit a fizikai részéről:
Amíg él az npc, a fizikai reprezentációja egy sima kapszula shape-el rendelkező proxy karakter-kontroller, ami bevett Havok-os berkekben, de ettől még nem egy nagy szám (lépcsőzés sincs megoldva pl).
Ha elpusztul, a progi kiveszi a szimulációból a proxy-t, és egy ragdoll-t tesz a helyére, amit ezután a fizika az erőhatásoknak megfelelően mozgat. Itt nem látszik sok minden, mivel a ragdoll egy rigidbody-ból áll. A lényeg, hogy működik a módszer.
Még van egy extra fícsőr benne, amit még nem tudok megmutatni, nevezetesen az, hogy ha az élettelen test elég sok sérülést kap, akkor szét fog esni/robbanni, de ahhoz még kellene egy gib-system is.Apropó, ha már szóba hoztam:
Nemtom ki hogy van vele, de nekem sose tűnt elégnek, ha egy játékban egy gonosz ellenfél kap egy megatonnát az arcába, és ahelyett, hogy szétszaggatná a töltet, csak elrepül pörögve.

Igényesebb eszűek a videó megtekintése előtt előre-hátra hajlongva 1 percig ismételgessék a ’Ez csak placeholder, ez csak placeholder’ mantrát, hogy elkerüljék a vizuális sérülést. :3

Videó: 

Címkék:frag Szólj hozzá!

_fpeti_ 2010.09.22. 02:01

Saját 3D-s modellformátum

Szerintem mindenki, aki három dimenziós játék írására adja buksi fejét, szembesül azzal a ténnyel, hogy 20xx-et írunk, és alig van olyan model formátum, amire egyértelműen azt lehet mondani, hogy elég lesz egy kisebb játékhoz. Nálam nagyjából ezt jelenti:

- stabilan működik az exporter
- könnyen betölthető
- képes csont alapú animáció(ka)t tárolni
- normalmapping-hoz van benne tangens vektor
- esetleg vertex color exportra is képes

Küszködtem .x parserrel Blender alatt eleget, hol működött az exporter hol nem, néha csak felét tolta ki az adatoknak. Ráadásul per face adta az adatokat, az egészet fel kellett dolgozni és kiválogatni az egyedi vertexeket, számolni a tangenseket. Ehhez nyilván kell egy plusz tool, ami kényelmetlen fejlesztéskor, mivel minden export után még azt is le kell futtatni, és csak ezután derül ki, hogy az engine-ben is jól szuperál-e a model.

Egyszer ebből elegem lett, és megnéztem az Blender .x Python exporter szkriptjét, bonyolult-e sajátot írni. Kiderült, hogy nem annyira bonyi, ráadásul a Blenderben nem csak per face vannak meg a vertex adatok, így előállítható egy ismétlések nélküli, hatékonyan rajzolható mesh. Azt nem mondanám, hogy egyértelműen, mert a vektorokon kívül minden vertex adat  (normal,vertex color, texcoord,tangens) face-enként van meg, de minden  face csúcs vektora tartalmaz egy indexet is egy központi vektor listára. Ebből az indexből kiindulva meg lehet csinálni az áhított vertex listát, ami a lehető legkevesebb adatot tartalmazza. Utána már csak ki kell menteni az adatokat fajtánként.
Az animáció már húzósabb, elég bonyolultnak tűnt, az copypaste lett, és egyelőre csak 1 animációt tartalmaz, valamint minden frameben kell minden csontnak animációs mátrix. Ez még változhat, mert az animálás most jön a játékban. A csontok hierarchiáját is elég egyszerűen oldottam meg, nem kell kapcsos zárójel erdő, mint a .x-ben, elég 2 kis integer tömb, az első a mátrixok számolásának a sorrendjét adja meg, a másik pedig az mátrix ősét a fában. A formátum kiterjesztése ’m’ lett.

Ezeket tudja eddig:
- vektor
- normális
- color
- textúra koordináta
- textúra neve
- tangens
- index buffer – háromszög lista
- skin info:
   - vertex súlyok
   - vertex indexek a súlyoknak
- csontok nevei
- csontok alap transzformációi
- mátrixok számolási sorrendje/ős-indexek
- animációk (még csak 1)
   - animáció neve
   - framek száma és indexxe
   - mátrixok minden csontnak minden frame-re

A formátum lehet text és bináris is.
Fő a kényelem alapon csináltam egy betöltő dll-t is, ami csak standard c hívásokat használ, így könnyen csatolható olyan környezetekhez, ami tud dll-eket kezelni. Valamint elkészült a model nézegető progi is (mviewer), amivel rákattintva a .m filra egyből meg is lehet nézni color/vertex color/texture/normalmapping módban is, valamint az animációkat is lejátssza, ha kell. Ha megállja a helyét, akkor az egészet nyilvánossá teszem.

Még annyit hozzáfűznék az egészhez, hogy elég sokat szenvedtem a Blender OGl és a D3D koordináta rendszer inkompatibilitásával. A model nézegetőben némelyik háromszögön jól jelent meg a normal map, némelyiken negálva volt. Akármerre állítgattam a tangenst, sosem volt jó mindenhol. Végül arra jutottam, a tangens jól áll, a normális is, csak a bitangensnek (amit én a shaderben számolok) kéne fordítva lennie. Így szimplán negálom ott, és kész. Van is egy videóm hasonló témában, kicsit vicces lett.

 

 

Szólj hozzá!

_fpeti_ 2010.09.14. 03:28

Kezdetnek egy kis win32: Erőforrások és a VS2008EE (C++)

Modelnézgetőt írtam, és szükségem volt egy effekt textfile-jánaknak a programhoz csatolására. Ha ugyanis rákkattintunk egy programhoz rendelt filera, a munkakönyvtár nem az exe könyvtára lesz, hanem a file-é amire klikkeltünk, így az exe könyvtárában tárolt fileokat nem tudja elérni. Lehetne központi helyen tárolni az exe helyét (registry) de abban nem vájkálok, amíg nem muszáj. Mivel az express verziókból kivették a resource-okkal foglalkozó részt, nem működnek az 'adjunk hozzá ilyen meg olyan erőforrásokat a projekthez ilyen meg olyan gombokkal' tutorialok  :).

Kell leíró file .rc kiterjesztéssel, amiben nevekkel és típusokkal ellátott file elérések lesznek.
Nálam így néz ki:
------------------res.rc -----------------------
// resource(s)

#include "resource.h"


ICON_MAIN         ICON    "mloadericon.ico"
MYTXT_FILE    MINDEGY "effect.fx"
------------------------------------------------

Az első a progi ikonja, mely sokaknak ismerős lehet, a program fő ikonját adhatjuk meg vele, ha betöltjük az ablak létrehozásakor.
WNDCLASS::hIcon -jába kell betölteni valami ilyeténképpen:
----------------------------------------------------------------
#include "resource.h"
// ablak init (részlet):
WNDCLASS w;
w.hIcon = LoadIcon(Myinstance,MAKEINTRESOURCE(ICON_MAIN));

----------------------------------------------------------------
A .rc második sora az érdekesebb, a 'MYTXT_FILE' a hivatkozás, a 'MINDEGY' pedig meglepően a típusa. Nem mintha az MS-nél ennyire elszabadult volna a 'Hungarian Notation' irányba, hanem egyszerűen nincs textfile-típus az erőforrások között, én adtam eme elmés nevet neki. A harmadik paraméter a file neve, ami egy text formátumú hlsl effekt file.
Mivel VSee nem hajlandó létrehozni/megnyitni az .rc fileokat, notepad-del lehet ezt elkövetni, majd hozzá kell csatolni a projekthez, mint egy sima .h vagy .cpp filet.

Volt még ott egy '#include "resource.h"' is, amit szintén nekünk kell megírni, ebben vannak a neveknek megfelelő integer értékek #define-ok formájában, így a MAKEINTRESOURCE() makróval lehet hivatkozni a nevekre (amúgy stringként kellene megadni a neveket, bemásolgatva mindenhova, nem annyira elegáns, mit ez.)

resource.h tartalma:
------------------------------------------------
//{{NO_DEPENDENCIES}}

#define ICON_MAIN        1024
#define MYTXT_FILE        1025
------------------------------------------------

A kommentes rész is fontos.
Ezt a filet lehet mindenhová include-olni, ahol használni szeretnénk erőforrásokat. A resource.h is természetesen csatolni kell a projekhez.
A standard win32 alap függvényeket biztosít a különféle cuccok betöltéséhez (a már említett LoadIcon,LoadBitmap stb), de textfile-ra nincsen töltike. Viszont bármilyen erőforrásra rákereshetünk a FindResource() fv vel, aminek kell a id-ja és a típus.
Ha nem null-t ad vissza, akkor a LoadResource()-al lehet 'globális' memóriába tölteni. Majd a LockResource() ad erre egy void* pointert, amit én a saját char típusomra (int8) alakítok. (nem is bonyolították túl, mi?)
--------c(pp) kód-----------------------------------------
HRSRC h = FindResource(NULL,MAKEINTRESOURCE(MYTXT_FILE),"MINDEGY");
if(h!=NULL)
{
    HGLOBAL a = LoadResource(NULL,h);
    if(a != NULL)
    {
        peffecttext = (int8*)LockResource(a);
        if(peffecttext)

       {
          // tölthetjük is az effektet befelé, D3DXCreateEffect()-el.
       }
    }
}    
-------------------------------------------------

Ez a módszer sok más nem támogatott file típusra is alkalmas lehet, csak tudjuk mit kezdeni a kapott memóriakupaccal. (A void*-tól rettegőknek nem ajánlott a módszer.)

UPDATE:

Release verzióban akad ezzel egy kis gond, mégpedig az, hogy a szöveg végén nincs nulla, amitől rácsoroghatunk nemkívánatos memóriarészekre is. (valami 'PAD(' rész van a végén nálam, gondolom paddig.)
Megoladásként használható a 
SizeofResource(NULL,h);
Ezzel le lehet kérdezni resource méretét byte-ban, s ennyit átmásolva stringbe és hozzadva a nullát a végére már oké.

Címkék:win32 resources Szólj hozzá!

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