_fpeti_ 2019.12.21. 13:43

Compiling Physx 4 with Cmake and Python

If 'generate_projects.bat' does nothing, you'll probably missed this to click during installing python:

clickthis.png

The other problem when compilin' physx4 in VS2019: <typeinfo.h> got renamed <typeinfo>. Had to rename in PsAllocator.h then everything worked fine.

Szólj hozzá!

_fpeti_ 2019.01.21. 19:05

PhysX opensource lett..

Alig van hozzá példaprogram, pedig jó cucc.
Heightmap-es sampleben van egy ilyen rész az adatfelöltésnél:

samples[x+y*hfSize].setTessFlag();
samples[x+y*hfSize].materialIndex0=1;
samples[x+y*hfSize].materialIndex1=1;

Az első sor nem csinál semmit, mert a setTessFlag() a 'materialIndex0' 7. bitjét állítja, amit felülír a második sorban, vagyis alulra kell a felső sor.

Valamint nem árt odafigyleni arra, hogy a heigthmap adatok feltöltésénél meg kell cserélni a x/z-t, tehát:

samples[y + x*vertexdim].height =  *((PxI16*)&heigthtmap[x + y*vertexdim]);

Címkék:PxHeightFieldSample PxHeightField PhysX Szólj hozzá!

_fpeti_ 2018.12.07. 01:09

Gdiplus::Bitmap::FromFile() és a nullás pixelalfa

Jó dolog a GDI+ pl be lehet vele tölteni mindenféle képformátumot Gdiplus::Bitmap objektumba és lockolva megkapjuk a pixeleket, amivel kezdünk valamit. Nincs vele gond, amíg egy pixel alfája nem nulla. Ha az, akkor az RGB is nulla lesz. Normálmap+specular alpha esetén nem az igazi, mert ahol kicsit se csillog, ott feketeség lesz.

Címkék:GDI BITMAP ALPHA Szólj hozzá!

_fpeti_ 2017.12.21. 01:24

Bullet physics - VS2013 kalandok

A honlapján van a CMAKE-es módszer, vagy a minden könyvtárba bemenve minden file-t hozzáadni a projekthez játék, ami elég hosszadalmas, én így csináltam:
1 Bemásolom a bullet gyökeréből az SRC mappát a projekt mappába.
2 Solution Explorer-ben fönn van pár pici ikon, a 'Show All File' kell nyomni - így mutatja az SRC mappát.
3 Jobb gomb a már látható SRC mappán és 'Include in projekt' - Ettől az összes file bekerül a projekbe, nem kell minden mappában mindet külön kijelölni.

Ekkor ugye fordulnia kéne, de valszeg nem fog, mert kell neki vmi CL\cl.h. Ilyen mappa nincs, ezt külön kéne feltenni, vmi OpenCL-es büntetés. Elvileg a MiniCL-t kéne - talán - használnia, de nem teszi, ha tud vki megoldást erre, írja meg. Szerencsére ki lehet lőni a projektből, ha nem gond, hogy a softbody-s szimulációt is ki kell gyomlálni, mert használja:

4. BulletMultiThreaded, BulletSoftBody, MiniCL mappákra nyomtam egy jobbgombot, exclude from project.

Zs már fordul is hiba nélkül.

Szólj hozzá!

_fpeti_ 2017.12.21. 01:24

Az 'AMD Gaming evolved' is lehet bekaphatna már valamit

Két napja tettem új drivert a sokat látott AMD6670 karinak, amivel a fent említett app is jött (Windows7 Home prof edition). Ma észrevettem, hogy a directx11-es IDXGISwapChain::Present() kifagy - egy idő után. Általában 10-20 másodpercnyi működés után, csak debuggolás közben. Először saját hibára gyanakodtam, valami pointer-bravúr ráfolyt, vagy ilyesmi. Amikor már semmit nem futott a progiból, csak az üres képernyő, de még mindig fagyott, akkor kezdett gyanús lenni, nem itt van a baj.
Ezután jutott eszembe, hogy megnézek régebbi projektet is, és ott is ugyanez volt: ha simán elindítom a debug buildet minden ok, ha F5-tel debuggolok, akkor fagy. Innen jöttem rá, hogy a hiba nem nálam van.

Ha kikapcsoltam a ezt a Rapt-nak is becézett fostengert, akkor minden oké lett megint.

Nagy mák, hogy időben közel volt minden egymáshoz, mert egyébként nem sok esélyt látnék arra, hogy valaki rájöjjön, hogy egy háttérben futó jelentéktelen app nyírja ki a progiját - egyszer csak váratlanul.

Szólj hozzá!

_fpeti_ 2017.10.30. 20:54

DirectSound

Gondoltam csinálok egy pici framework-öt, ami minden installálás nélkül fut kb. bárhol. Hangnak DirectSound-ot gondoltam, elég régi cucc, de még megy, nem kell neki semmi extra dll-t installálni. Annyi gond volt vele, hogy nem  találtam más tutorialt, mint a Rastertek-eset. Ebben, ha betöltöttünk egy wav-ot, így kell létrehozni, hozzá a buffert,amit a DS le tud játszani:

result = m_DirectSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL);
if(FAILED(result))
 return false; 
 
result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&*secondaryBuffer);
if(FAILED(result))
return false;

Szóval kell egy temp buffer valamér, utána kell megcsinálni a 'secondaryBuffer'-t, ami lejátszható.
Nekem a QueryInterface() E_INVALIDARG-ot ad vissza. Poénból megpróbáltam a tempBuffer-t
lock-olni, betölteni abba a hangot.. és le lehet játszani. Úgyhogy a bohóckodás nem kell a QueryInterface()-el.

 

Szólj hozzá!

_fpeti_ 2017.08.03. 22:17

C++ fordító mágia

Van ez a cseppnyi kód:

#include <iostream>
using namespace std;

class f
{
public:
   f() { v = 0; }
   f(int a) :v(a) {};
   const f& operator=(int a) { v = a; return *this; }
   const f& operator+=(const f& m) { v += m.v; return *this; }
   int getv() const { return v;};
private:
   int v;
};

void main()
{
   f test;
   test = 1;
   test += 5; // this works without f::operator+=(int) !
   cout << "so test is = " << test.getv() << endl; // prints '6'
}

Nekem érdekesnek tűnik, hogy a fordítónak nem okoz gondot, hogy hozzáadja az '5'-t anélkül, hogy lenne hozzá megfelelő operátor-túlterhelés. Debug-ban végigmenve kiderül, mit is csinál a vs2013c++ fordítója:
csinál egy temporális 'f' példányt, majd meghívja neki az op=(int) fv-jét, így értéke 5 lesz, majd ezt hozzáadja a 'test' példányhoz az op+=(const f&) segítségével.
Azaz rájött, hogy a meglévő függvényekkel meg tudja oldani a feladatot. Szerintem durva, hogy ilyenre rájön.

Szólj hozzá!

_fpeti_ 2016.06.05. 01:40

MS Visual c++ 2010 és a -1.#IND, ami csak release-ben jön elő

Néha előfordul a fenn említett rendszerrel, hogy release-ben full optim mellett mondjuk 3 float összeadása eredményeképpen +-1.#IND lesz a végeredmény. Nálam 3d vektor dotproduktja produkálta, a netet nézve úgy néz ki másnak is volt hasonló kalandja (x*x+y*y = #ind). Ha kikapcsolom az optimalizációt, elmúlik, de lassabb a program (180fps helyett 70).
Mit lehet tenni? Le kell cserélni, mert egy régi szar. 2013-on már jól megy.

Szólj hozzá!

_fpeti_ 2014.11.30. 23:58

Átállás Havok (hk2014_1_0_r1) régebbiről (vs2010EE alatt)

Ha van egy ilyen hiba:

hkGeometryUtilities.lib(hkMemoryMeshTexture.obj) : error LNK2019: unresolved external symbol "public: static class hkImage * __cdecl hkImageDecoderUtil::loadFromFile(char const *)" (?loadFromFile@hkImageDecoderUtil@@SAPAVhkImage@@PBD@Z) referenced in function "public: virtual class hkImage * __thiscall hkMemoryMeshTexture::Sampler::getImage(int)const " (?getImage@Sampler@hkMemoryMeshTexture@@UBEPAVhkImage@@H@Z)

Akkor ez a lib hiányzik neki:

hkImageUtilities.lib.

Szólj hozzá!

_fpeti_ 2014.03.01. 02:24

directx11 shader hiba

Mivel töltöm időmet: ez a kódrész azt eredményezi, hogy a konstans bufferre azt azt adja ki a dx runtime debugging, hogy 16 byteot adok meg (vec3 + pad), de 48 byte kéne neki.

Texture2D Texture[3];
SamplerState texSampler;

cbuffer whatnot
{
float3 viewposition;
};

#include "deferredfunc.c"
#include "cotangetframe.c"

Ha az #include-ok a file elejére kerülnek, elég neki a 16 byte, vagyis rendesen működik. Nem tudtam megtalálni, miért 48 byte kell neki, semmilyen más betöltött shadernek/cbuffernek nem kell ekkora buffer.

Szóval include-ok legfelülre mennek, vagy nem lehet tudni, mi lesz.

 

 

 

Szólj hozzá!

_fpeti_ 2014.01.25. 00:56

XAudio2 hiba

Véletlenszerűen kihagyott hangokat a játékom, gondoltam bekapcsolom a xaudio2 debugger funkcióját, ezzel:

HRESULT r = XAudio2Create(&xaDevice,XAUDIO2_DEBUG_ENGINE); 

Ez annyit csinált, hogyha meghívtam egy ilyet:

IXAudio2SourceVoice::Stop(XAUDIO2_PLAY_TAILS); // csak ezzel a parammal csinálja!!

Akkor széjjelfagyott a progi a Stop() fv.-ben. Ha nincs debuggolás, minden ok.
A hibáról egyébként kiderült, hogy lejátszás közben töröltem hangokat, IXAudio2VoiceCallback::OnBufferEnd() lefutása után kell törölni, én mást néztem, így már megy szépen, a debuggolást meg el is felejtem, mert csak bajt okoz, ráadásul nem is nagyon sok mindent lehet vele kideríteni. Kb annyit, hogy le volt-e terhelve az XA engine..sokat ér.

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

_fpeti_ 2013.02.25. 00:47

Rossz blendelési súlyszám

Volt egy érdekes hiba, ami elvitt pár órát. A modelnézegetőt bütyköltem, de egy sarok körüli összes háromszögön a textúrázás rossz volt (a villa jobb ágának tövében kell keresni)
blend3.PNG

El nem tudtam képzelni, mi lehet a baja, mindenhol jó volt, csak ott nem 6 darab háromszögön az ominózus vertek körül, pedig minden háromszögnek külön vertexlistája volt. Minden adatot megnéztem, visszafejtettem a vertexbuffer adatokat, minden stimmelt, próbáltam még FVF fixed módon is előidézni a hibát, de nem sikerült. Az a nagy háromszög a csíkos textúrával annak az eredménye, hogy 2 vertex súllyal rajzoltam ki, és ettől a textúra elromlott..
Aztán kiderült, hogy ha nincsennek a vertex struktúrában a blendindex/weight adatok (2 súly +index per vertex) akkor nincs baj. De akkor miért nem rossz több helyen is a dolog? Végül átnéztem az eredeti modelt, amit kiexportáltam, és kiderült, hogy 3 súly is van néhol, de csak kettőt ír ki a konverter a végső file-ba. Ez nem magyarázza meg, miért a textúrázás romlott el, miért nem az animáció, és miért csak 1 helyen, ahol 3 súly kellett volna, de máshol is volt ilyen vertex. Kijavítva a konvertáló-bugot 3 súllyal már működik. Vertex méret, vertex adatok elhelyezkedése, vertex-deklaráció minden jó volt 2 súllyal is - ezt a progi automatikusan építi fel a model adataiból- de ha hiányzott a harmadik súly, széthúzta a textúrát. Vagy a tu vagy tv koordináta 1 volt az egész háromszögön, PIX-el is megnéztem, ott jó textcoordokat mutatott minden sarokban a vs_output-nál. Annál mélyebbre meg nem lehet menni vs/ps debugolásban. Rejtélyes, de ha megfelelő minden, akkor nem jön elő, lehet csak a régi vga-m szórakozik.

Címkék:hw-skinning textureproblem Szólj hozzá!

_fpeti_ 2013.02.25. 00:38

Modelformátum, hát már megint itt vagy.

Volt nekem egy problémám a content pipeline-omban. Már ha azt a pár poligonhalmazt kontentnek lehet nevezni, amiket összebarmoltam Blenderben tesztelés gyanánt. Nekiveselkedtem pár éve és összekínlódtam egy 50kb-os python-scriptet, ami szépen működött, a Blender 2.4x-es verzóiban. 2.5-tel jött a nagy pofáraesés, az eredeti szkript minden sora minimum egy helyen dobott egy hibát, így dobhattam el az egészet. Mivel nem rajongok a pythonért, gondoltam az egyetlen ésszerű dolog, ha meglévő formátumot használok, ami tényleg jó ötlet, hisz egy népszerűbb formátumba minden 3d-s szoftver tud menteni, de milyen jó lesz.
Ránéztem hát az Autodesk által fémjelzett FBX formátumra, amihez még SDK-t is adnak, ami betölti a file-t, én meg csak kiírom saját formátumomba, minden van benne, ami valaha csak kellhet. Elég jól is ment a gyér dokumentáció ellenére is, csak az animációnál akadtam fönn azon, hogy a Blender (2.6.5) fbx exportere minden frame-et kiexportál, nem csak a keyframe-eket.
Ez annyit jelent, hogy ha van 2 keyframe-em, mondjuk 1-es és 100-as képen a időskálán, akkor 100 transzformációt ír ki minden csontnak. Ezt én erős túlzásnak tartom, és kiderült, nem is teljesen ennek kéne lennie, azaz az exporter nincs a helyzet magaslatán. De azt is olvastam, hogy ez az fbx formátumot amúgy is sokszor mocap adatok átvitelére használják, ahol kb minden képkockán változhatnak a transzformációk, azaz megszokott, hogy minden pillanatra van külön adat. Most mit lehet tenni, másodpercenként 25 képpel számolva egy 10 mp anim 250 keyframe, mondjuk 10 csontra 2500 mátrix lesz az engine-ben, kicsit sok, megjegyzem az fbx szögekben tárolja a forgatásokat.

Nekem ez egy kicsit sántított, így vettem egy nagy levegőt, és ’együltömben’ írtam egy másik szkriptet az újabb Blenderhez, ami nem 50 hanem 5kb lett. Simán kidumpolok mindent egy köztes text-fileba, semmi extra kód, csak face-data, skinning, és animáció.
Írtam egy szimpla c++ konzolos progit, ami ezt a köztes filet beolvassa és előállítja a végleges adatokat az engine-nek, és azt már emészthető formában file-ba írja. Ezzel azt értem el, hogy ahelyett, hogy minimalizáltam a Blender-függő kód mennyiségét, így sokkal könnyebb frissíteni, ha valami változik. A konverter progi meg nagyjából marad mindig ugyanaz, hacsak nem kerül be valami extra, de cpp-ben nem nagy ügy.
A köztes file kiterjesztése mra lett (m-raw rövidítve). A kész modelfile .m típusú, hasonló a régihez, de pár dolgot hozzáadtam. Pl a régi csak 1 textúrát tudott kezelni, ami nem volt túl jó ötlet így visszagondolva.
Így van most egy Blender -> szkrtipt(python) -> .mra(texfile) -> mraimporter(c++) -> .m(textfile)  útvonalam.
Ezeken kívül van egy modelnézegető progi (mviewer.exe) és egy C-s dll, ami ’m’ fileokat olvas be, megkönnyítve bármilyen programban a használatukat.

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

_fpeti_ 2012.05.21. 23:19

Repülő npc-k és a Havok

 

Jól elszórakoztam ezzel is, az Intel-es Havok fórumon is tiszteletemet tettem, ahol mondották, hogy hát 100 féle képen meg lehet oldani egy hkpCharacterRigidBody reptetését. 0-ra állítom a gravitciót és wiiiii, már száll is amerre akarom!
Ez igaz, de ha hozzáér bármihez a talpán, akkor odatapad, mert beindul a gyalogló-algoritmus, csúszósíkok számolása, stb. Ráadásul  a hkpCharacterContext::update mindig nullázza az y-t a mozgási irányban, így hiába adunk meg a hkpCharacterInput::m_forward-ban függőleges mozgási irányt, az csak vízszintes síkon hat. Így aztán én inkább kitaláltam magamtól, ahogy szoktam. :)
A megoldás:
ne vegye észre a kontroller, hogy áll valamin, amit ezzel lehet elérni:
hkpCharacterInput::m_surfaceInfo.m_supportedState = hkpSurfaceInfo::UNSUPPORTED;

A kontroller mozgatása ezután már működik, nem a hkpCharacterInput-on keresztül persze, hanem közvetlenül a rigidbody sebességét kell állítani, vagy a gravitációt +- irányba beállítani.

Elsőre furának tűnt egyébként, hogy nincs standard repülő-npc megoldás egy drága 'industry-standard api'- ban, de ez talán nem is olyan meglepő, ha a mai 3d-s játékokat nézzük. Ritkák manapság a repülő szörnyek, maximum helikopterek, azokat meg meg lehet oldani egyszerűbben is. Azok nem szoktak falakról visszapattanni, csúszkálni :3.
 

Szólj hozzá!

_fpeti_ 2012.05.19. 23:20

Non-blocking UDP server

Ezt kell a server kódba bind() elé tenni, és akkor a recv() és társai nem állnak le várni az infót. Ezt nem könnyen találtam meg a neten, hátha így könnyebb lesz másnak. :3
u_long on = 1;
ioctlsocket(Socket, FIONBIO,&on);

 

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

_fpeti_ 2012.04.29. 04:41

Öntapadó kézigránát.

 Él-e még valaki, aki ismeri a Shadow warrior nevű mókás szoftvert? Játék '97-ből, 3DRealms alkotása, akik a Duke Nukem-et is elkövették. Kb. ugyanaz a motor, nagyon elborult játék volt ez is. Volt benne egy 'sticky grenade' nevű tüskés gömb, amit el lehetett dobni, ha ellenfélre esett, akkor ráragadt és kis rohangálás után felrobbant. Ha falhoz csapódott a gránát, akkor egy mozgás érzékelős akna lett belőle, ha közel ment valami, akkor robbant fel. Lehet inkább a Halo-féle plazmagránáthoz kéne manapság hasonlítani.
Gondoltam nem árthat, ha én is megcsinálom :3.
Így három üzemmódja lett a kis piros gránátnak:
Sima időzített, ez most 4mp után robban, de lehet kézben kibiztosítva tartani, így lehet vele trükközni, hogy a levegőben robbanjon. Mondjuk túl sokáig nem érdemes szorongatni.
A ragadós változat mindenre rátapad, de az időzítő tovább fut, és ennek lejártával 'detonál'.
A harmadik mód az 'impact' nevet kapta, ez azonnal robban, ha hozzáér valamihez.
Rövidke demonstráció:
VIGYÁZAT: hangot is vettem föl, ami elég hangos.


Aki figyelt, annak feltűnhetett, hogy két hasonló robot van a képen. A távolabbit TALÁLTAM a kódban, egy régebbi verzió, de működik, csak nem csinált semmit azon kívül, hogy rázta a lábát, vagy ha észrevett, akkor próbált odajönni. Megfejeltem annyival, hogy ha közel ér, akkor mi mást is csinálna...  felrobban. Kezdem magam 'Michael Bay'-nek érezni :).

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

_fpeti_ 2012.02.13. 02:38

Új effekt

 Alphablendinggel nagyon sok olyan dolgot meg lehet csinálni, ami elég jól néz ki, de nem bonyolult megcsinálni. Csináltam is egy 'animált' (forog 'áze) jelenséget, de nem tudom mi a neve. 'Teleportálási effektnek' hívom. Minecraft-ból jött az ötlet (lehet néha mással is kéne játszani). Ott az 'End' dimenzióban a sárkány legyőzésekor láthatjuk. Csináltam egy kis modelt Blenderben, pár tucat 3szög, és mindegyiknek van egy csúcspontja középen. Semmi más nem kell, a színeket és a alfa mértékét a pixelshader elintézi. Eleve 'hw instancolósra' írtam, így sokat ki lehet belőle rajzolni egyszerre.

 

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

_fpeti_ 2012.02.09. 03:16

Videókártyán számolt magasságtérkép árnyék.

 Van nekem egy magasságtérkép szerkesztő progim, nem egy nagy szám, van pár funkciója, többek között árnyékot is tud számolni, majd elmenti png-be. Eredetileg az árnyékot cpu-n számoltam, elég sok háromszög-sugár ütközés volt benne, és kb 10 percig tartott, mire egy 512x512 heightmap-en kiszámolt egy 2048x2048-as árnyéktérképet. Ráadásul nem is volt túl szép, még blur-ozni is kellett. Gondoltam, kipróbálom mi lenne ha gpu-n tolnánk a sugarakat, csináltam már afféle godray alapú árnyékokat 2d-s játékmotorban, ide pont jó lenne.

Elég egyszerű a dolog, kell hozzá 2 rendertarget textúra, az egyikbe készül a magasságtérkép, a másikba a shadowmap.
Az első mérete elég ha akkora, ahány cellából a térkép áll. Ebbe bele kell renderelni a hieghtmap-et úgy, hogy a legmagasabb pontja legyen 1, a legmélyebb pontja pedig 0. Ez nagyon könnyű, még projekciós mátrix sem kell hozzá. Csak -1 +1, és 1 -1 közé kell konvertálni a heightmap vecktorok xz komponensét, (vertex shaderben) majd a PS-nek átadva az y koordinátát azt elosztja a magasságtérkép legnagyobb magasságával, ezzel 0-1 közé konvertálja azt. (ha a lehet a vektor.y negatív, akkor még attól relatívvá kell tenni)

 

Kb ennyi a shader kód:

 

float2            origo; // hülye név csak a cellaszám felét adja meg

float2            zproj; // ’.x’ a minimum y, .y a himap magassága abszolút

 

void vs_himap(

            // input data

            float4 pos              :POSITION,

            float3 n                :NORMAL,

            float4 color0           :COLOR0,

            float4 color1           :COLOR1,

 

            // output

            out float4 opos              :POSITION,

            out float opixelheight  :TEXCOORD0)

{

      opos.xy = (pos.xz/origo);// world coord to x: -1 -> +1 y: +1 -> -1

      opos.zw = float2(0,1);

      opixelheight = pos.y;   // ps needz it

}

 

 

// simple diffuse with one color

void ps_himap(          float pixelheight :TEXCOORD0,

                        out   float4 oColor           :COLOR)

{

      oColor = (pixelheight-zproj.x) / zproj.y;

}

 

Most ebből számoltassam már ki a árnyékot, mégpedig úgy, hogy minden pixel koordinátájából a nap fele megnézünk egy csomó pixelt, és ha magasabb, mint a sugár y értéke ott, akkor árnyékol, csökkentsük a végső árnyékpixel-intenzitást. Ez gyakorlatilag egy csomó ’texture-fetch’ (pixel szín kiolvasás textúrából), ami talán a leglassabb, amit a gpu-n lehet. Egyébként ezt a módszert használják a pálmafa-levélen átszűrődő fénycsíkok rajzolására is a Crysis-ben például.

Kód:

float3            Invlightdir;

float2            HalfPixel;

 

texture Thimap;         // heightmap

 

// Himap

sampler Shimap = sampler_state

{

Texture     = <Thimap>;

MinFilter   = POINT;

MagFilter   = POINT;

MipFilter   = POINT;

AddressU    = CLAMP;

AddressV    = CLAMP;

};
void vs_shadowmap(

            float4 pos              :POSITION,

 

            // output

            out float4 opos         :POSITION,

            out float2 texcoord     :TEXCOORD0)

{

      opos = pos;

      // -1 -> +1 +1->-1 map to 0-1,0-1

      texcoord.x = pos.x*0.5 + 0.5;

      texcoord.y = (-pos.y)*0.5 + 0.5;

 

      texcoord+=HalfPixel;

}

 

 

void ps_shadowmap(           float2 texcoord         :TEXCOORD0,

                             out   float4 oColor           :COLOR)

{

      const int ITER = 256;

      float3 texadd = Invlightdir;

      float basehi = tex2D(Shimap,texcoord).r;

      float3 tc = float3(texcoord.x,basehi,texcoord.y);

 

      float finalcolor = 1;

      for(int i=0;i<ITER;i++)

      {

            tc+=texadd;

            float h = tex2D(Shimap,tc.xz).r;

            if(h>tc.y) finalcolor -= 0.01; // soft shadow lesz

      }

      oColor = finalcolor;

      oColor.a = 1; // csak hogy lássuk

}

A vertex shader nem nagy vaszidszdasz, egy target méretű négyzetet rajzolunk, aminek a koordinátái már -1 +1 közé esnek, csak a textúra koordinátákat kell ebből kiszámolni – át is lehetne adni a VS-nek, de mindegy.

A lényeg a pixelshaderben van (ps_shadowmap). A texadd az a növekmény, amit minden iterációban hozzáadunk a pixelpozícióhoz (tc). Kicsit bonyinak tűnhet, de nem az. A tc.xz a textúrakoordináta, a tc.y pedig a magassága a pixelnek a hieghtmap textúra alapján. Így a texadd.xz a texcoord növekmény, a texadd.y pedig a sugár emelkedésének növekménye pixelenként. Igazából itt van a cica elásva. Ez az Invlightdir –ból jön, amit be kell állítani a hieghtmapnek megfelelően. Az x és z komponens az egy pixelre jutó textúrakoordináta növekmény, mondjuk 512x512 heightmap textúra esetén 1.f / 512. Az y pedig az egy pixelre jutó sugáremelkedés. Ezt úgy kapjuk meg, hogy a heigthmap maximum magasságával osztjuk a normált raydir y komponensét. Inkább beszéljen a kód:

 

VECTOR smallm = Lightdir; // normalized!

smallm.y /= heightmapysize;

float pixelnum = float(HieghtMap.GetTexSizeX());// heightmap textúra mérete (x==y nálam)

smallm.x /= pixelnum;   // osszuk le pixelméretre

smallm.z /= pixelnum;

 

S ezt a ’smallm’-et lehet beállítani az effect ’ float3 Invlightdir’ paraméterébe. S kész is. A kérdés csak az, megérte-e a hardvert használni? A szoftveres 10 percig fut – ez 2 EZREDMÁSODPERCIG! Szóval sokkal gyorsabb, és sokkal gyorsabban meg is lehet írni.

Pár apróság, hogy ne menjen el másnak erre egy este:
- Képernyőnél nagyobb rendertarget-et csak megfelelő méretű z bufferrel lehet használni dx9 alatt, ehhez a SetDepthStencilSurface() a kulcs.

 

- rendertarget formátuma: a hieghtmaphez én a kedvenc D3DFMT_R32F-t használom, ez pontos és talán elég elterjedt. A shadowmap-hez próbáltam egy 8 bites formátumot, a D3DFMT_L8-at, amit a kártyám támogat is a dxcapsviewer szerint, de érdekes módon x irányban széthúzta a kb 4 szeresére a textúrát, 32bit helyett 8 bitbe próbáltam renderelni, talán azért, de ez nem indok arra, hogy ne működjön. Mindegy, inkább D3DFMT_A8R8G8B8 lett, ami 4-szer annyit foglal, de úgyse kell sokáig, csak amíg kimentjük fileba. 

Végül egy kép, hogy mégis, a kék a magasságtérkép, a fehér a shadowmap.

esetleg egy részletesebb, 64 iterációval és nagyobb fényerőcsökkentéssel:
 

 

Szólj hozzá!

_fpeti_ 2012.01.30. 00:52

Installer nyűgök: InnoSetup és DXSETUP nagy harca

Gondoltam nyitok a világ felé, és csinálok egy menő installer-es demót, mit csak le kell tölteni elindítani, várni míg végez, és élvezni a végtelen szórakozást. Manapság mindenki kényelemhez szokott, ha nem megy minden flottul, akkor legörbül a száj, és rajongókat veszít az ember. Ezért fontos a könnyed installáció – mondja a reklám.

Innnosetup-ot nagyon könnyű használni, szkript alapon működik, alap projektet is létre lehet hozni, be kell írni a könyvár nevét, ahol van a kész játék amit majd kitömörít a user célgépén abba a mappába (Program Files-ban valahol ált.), amibe kell. Kb. ennyi a minimum. Ez egy sor. Ez tartott órákig nekem? – nem. Hanem az, hogy a DirectX-es Visual C++ al készült cumóknak kell egy VC redist (vcredist_x86.exe) és egy DirectX-es install is. A vcredist_x86.exe-vel nincs gond, fenn van a neten, hogy kell paraméterezni, hogy silent módban – usert nem idegesítve – szépen fölinstallálja magát (nem Önt! :D). A DX-es rész kicsit bonyolultabb, ott minimum 5 file kell ahhoz, hogy egyáltalán elinduljon az install – miért is ne- plusz még a csomagok is, ezeket a dxsdk/redist mappájában találhatjuk meg. Nálam ez 11 file. Ezt szimplán úgy oldottam meg, hogy a kiadandó programban létrehoztam egy redist mappát, abba ment minden file, és miután ezeket az installer kibontotta a célgép mappájába, elindítottam a {app}/redist/ vcredist_x86.exe és a {app}\redist\DXSETUP.exe-t. Itt baj lett a dxsetup-nál, mivel azt írta ki, hogy nem találja a framedyn.dll-t. Kemény gugli-fu után olyan történt, ami még velem soha: kiderült, hogy ez nem az én hibám –ami rémisztően hatott. Kiderült, hogy a hivatalos MS álláspont szerint ez ’elszaródott Windows XP’ oprendszereken fordulhat elő, ahol megsérült, vagy törlődött ez a dll. Erre mit is mondhatnék. Meg lehet oldani, környezeti Path változóhoz a system32/wbem-et is hozzávenni, vagy csak szimplán bemásolni a dll-t a system32-be. Aztán én erre kérjek meg mindenkit, akinek előfordul?
Szerencsére kiderült, hogy e nélkül is lefut az install, valamint Vista és Win7 rendszereken nem fordul elő. Így talán nem érint majd túl sok embert, engem annyiban, hogy órákig kerestem a hibát a szkriptemben.

Az idő második része egy egyszemélyes dll-hárború vívásával telt el. Szerencsére valaki a konyhaasztalon hagyta éjszakára a mit sem sejtő win7-tel felvértezett ártatlan notebook-ját, így azon tudtam tesztelni, hogy ’meddig fagysz még’. Először hiányolt egy X3DAudio1_7.dll-t, amit nagy nehezen megtaláltam egy 2010 februári cab-ben.. Azzal azt  csinálta a progim, hogy elindult, fekete képernyő, utána kilépett. Megnéztem a log.txt-jét, kiderült, hogy elindult szépen csak az xaudio device nem jött létre, valamint egyetlen dx-es effect-file se tudott lefordítani. De nem írta ki, hogy hiányozna valami. Azért csak kerestem egy friss D3DCompiler_43_x86.cab-ot meg Xaudio, és XACT-ot is, ha már ott vagyok, sokat nem foglalnak az installerben. Ezekkel már ment szépen a cucc. Nagyjából 30-40 fps-en egy kétmagos asus gépen integrált intel cukiságos vga-val – 800x600-ban. Többre számítottam, ennyi a régi gépen is (gefGS7300)-on. Érdekes módon sokkal simábban ment a 2 magos gépen, úgy látszik van különbség ugyanolyan fps mellett itt. A lényeg, hogy megy.

Ide is másolom a InnoScript azon részeit, ami vonatkozik:

[Files]
Source: "C:\3d\release\*"; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs


[Run]
Filename: {app}\redist\vcredist_x86.exe;Parameters: "/q:a /c:""VCREDI~3.EXE /q:a /c:""""msiexec /i vcredist.msi /qn"""" """; WorkingDir: {tmp}; StatusMsg: Installing CRT...
Filename: {app}\redist\DXSETUP.exe; Flags: waituntilterminated;StatusMsg: Installing DirectX dlls...
 

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

_fpeti_ 2012.01.08. 02:07

Triplanar texturing és nagyobb decalek

Triplanar texturing: Textúrakoordináta számolása a csúcspont (vertex vektor) alapján, és több textúra 'összeblendelése' normál iránya szerint (normal.xyz adhat 3 faktort). Ez van a nagy kövön. :)
Meg nagy koromnyomok is. Gondolkoztam, milyen egyszerű lenne deferred shaderrel projektálni a textúrát a sziklára, de inkább belevágom a decal aabb-jébe a mesh összes háromszögét, és textúrakoordinátákat számolok nekik. Nagyon gyorsan nő a háromszögszám, hipoly-mesheken nem kifizetődő a dolog. Mesh vágáskor nagyon sok redundáns vektor keletkezik (minden elvágott élen lesz egy pár.) Ezeket ki lehet keresni, de félek elég soká tartana párszáz vektoron végigmenni párszázszor, hogy megtaláljuk az ismétlődőket. Mondjuk a nem számolt (meshből kapott) csúcspontokat könnyű összehasonlítani, bitre egyeznek (én float xyz helyett (int*)-ra kényszerítem és úgy hasonlítom.. elég vicces, de gyorsabb 2 integer közötti egyenlőség, mint a fabs(x0-x1)<delta cuccos.) Ha túl sok vektor/háromszög keletkezne, egyszerűen nem hozok létre új decalt. Nem annyira fontos, hogy mindenen legyen. Egyelőre ráadásul csak sztatikus objektumokon lehet ilyen, nincs per-frame decal transzformáció. Lehet így is marad. Mondjuk jó lenne ragdoll-okra is nagyobb decal-eket applikálni, ha nagyot sérül. Ekkor már csontozni is kéne a decalt, amihez nem lesz kedvem előreláthatólag soha. :3

bigdecals_triplanartex.PNG

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

_fpeti_ 2011.12.08. 23:19

Level of detail avagy LOD

Régi trükk: ha valami messze van, ne rajzoljuk ki a nagy felbontású modelt, hanem használjunk kevesebb háromszöget, messziről úgyse látszik. Nem bonyolult, nálam annyiban merült ki, hogy Blender-ből több modelt is lehet egy .m fájlba exportálni, az első model a hi-poly-mesh, animációkkal, textúrákkal.  A második megy egy low-poly változat, ami csak vertex-colort használ. Vannak játékok, amik sok LOD szinttel dolgoznak, (nem vagyok biztos benne, de mintha a Serious Sam 30+ LOD-ot használt volna  - az első játék, nem a legújabb). Manapság nagyon oda kell figyelni arra is, hogy hányszor rajzolunk egy frame-ben, ha minden modelnek lenne 30 verziója, az nagyon belassulna (dx9 alatt 300-500 drawcall kéne - pesze ez nem ökölszabály, de a dx9 virágzásakor ezt beszélték ;) )
Mivel a második LOD-os modelben nagyon kevés háromszög van, (<100) ezért semmiképpen nem érdemes külön-külön rajzolni őket. Én két módszert is választottam:
1. A nagyon kevés háromszögeket használó objektumokat szoftveresen forgatom térbe, és egy drawcall-al kimegy a cucc.
2. Ha nagyobb a poligonszám, akkor jöhet az a hardware-instancing, amivel csomó ugyanolyan objektumot lehet egyszerre képernyőre küldeni.

Végül, ha nagyon-nagyon távol van az az ojjekt, akkor kár fecsérelni modelrajzolásra az időt, és elég egy kis képként kirajzolni - ezt billboarding-nak is hívják.

Itt egy kép az első próbálkozásról, a három lod szint van: hipoli,lowpoli,billboard. Jól elkülönülnek, ami nem jó, de ennyire futotta a programmer art-ból mára.

Szólj hozzá!

_fpeti_ 2011.11.21. 01:51

Játékötlet (nem nagyon eredeti, de Minecraft ><; )

Mostanában nagyon gondolkodom egy MC klón félén, örömprogramozás céljából. Sokkal több kockával, (min 8x) nagyon szimpla egy szín (+tulajdonság) per kocka adat szerkezettel - lehetne 1 byte per 'voxel'. Alapból 256*256*256 kockákból állna a scene egy darabja, ez 16MB adat lenne egyszerre. (MC-ben 16*16*128-as oszlop.) Ha a cache-miss nem szól nagyon bele. Ebből lenne persze egyszerre több is benn a memóriában. A láthatóság nagyon egyszerű módon működne, ami az eredeti Minecraft-ben is nagyon szimpla - egyszerűen minden kockát kirajzol, aminek van olyan oldala, ami mellett levegő van. Ez zseniálisan egyszerű húzás, és nem is annyira pazarló, mint előre gondolná az ember. Én megfejelném egyfajta raytrace-szel, csak nem minden képpontnak lenne egy sugár, minek egy ilyen szabályos kockákból álló világban, hanem voxelről-voxelre ugrálna a ray, pont mint a 2d-s szakaszrajzoló algókban. Ez nem lenne teljesen pontos, az is fontos, hol helyezkedik el a kamera egy voxelen belül, ami hibákat eredményez(het). Erre még visszatérek, ha egyszer eljutnák oda. Itt akár még előjöhetne egy dinamikus, nap irányából jövő árnyékolás is, nem mindig fölülről jönne a fény, mint MC-ben.
De lehetne valamiféle durva z-buffer jellegű dologgal is próbálkozni, szigorúan fixpontos alapon.
Végső soron maradna a per pixel ray, de azt kétlem, hogy valós időben képes lenne sok mindenre. De majd kipróbálom.

Persze ott vannak a gpu-s módszerek is, pl ez a 256*256*256 beleférne egy 3 dimenziós textúrába is, és lehetne szórakozni Cuda/DirectCompute dolgokkal is, ezzel még pláne nem foglalkoztam, érdemes kipróbálni akinek van dx10 karija minimum.


Fák jól néznének ki átlátszó zöld lombbal - jó lenne valamilyen módon egyesíteni az átlátszó kockáit egy lombnak egy egységes geometriává, és úgy rajzolni, MC-ben elég darabosan néznek ki pl a jégkockák egymás mögött. Összefüggő erdőlombozatnál ez elég durva számolás lenne mondjuk.

Arra is gondoltam, hogy miért is rajzoljak sima kockákat, ha közel vannak a kamerához, lehetne használni egy kis extra geometriát, hogy ne legyenek annyira élesek a szélek. Nagyon egyszerűen meg lehetne nézni, hogy egy kockának melyik oldalain van szomszédja és aszerint rajzolni egy nagyobb felbontású kis 'mesh-escskét', hogy jobban passzoljon mondjuk egy leejtő oldalába. Tulajdonképpen a látható éleket kellene kicsit lekerekíteni, pl ha egy szomszédja sincs, akkor egy ortopéd gömböt rajzolnék ki. Elég sok kombó van, hisz 26 kocka szomszédja lehet, forgatásokkal lehetne csökkenteni a mesh-ek számát, ami szvsz nem annyira menő (még forgatni is kelljen?). Vagy a fontos szomszédok számát is lehetne csökkenteni, mondjuk csak az oldalaihoz érőket figyelembe venni - így csak 6 elemből kell kikombinálni. Nyilván ezt ki lehet számolni előre, és csak akkor kell módosítani, ha változik körülötte valami.
Ez az egyik iszonyatos előnye a kockavilágnak, hogy ahhoz képest, hogy teljesen dinamikusan lehet változtatni mindenen, nagyon sok mindent előre is ki lehet számolni, majd ha változik valami - ami általában kockák elhelyezése vagy eltűnése a világban - akkor kell újraszámolni a változástól függő dolgokat. Ilyen szintű rugalmasságot nem lehet elérni semmilyen más módszerrel.

Apropó kockák lerakása, a játékmenetet  - már ha lesz valaha, amit kétlek így az első kódsor megléte előtt - én nem annyira a kreatív vonalon mozognék, egyébként is kis kockákkal bíbelődni milyen már, inkább felfedezős-akciós-lyukrobbantós mezsgyén képzelem a dolgot (mint mindig). XD

Ez persze nem jelenti azt, hogy nem lehet találni semmit, pl. szép átlátszó drágaköveket (azérse gyémántot :) )  amiért itt-ott lehetne táposabb cuccokat venni, vagy csak megdobálni vele az ellent.. semmi 'crafting', meg bonyolítás, az ilyesmi gyönyörűen meg van írva az MC-ben, minek másolni. Tul. a kockákból felépített álló világon kívül nem sok mindenben kéne, hogy hasonlítson MC-re, de mindenkinek ugyanaz a játék fog eszébe jutni róla.

btw ellenfelek: mi lenne, ha azok is kis kockákból állnának és 'behatás' esetén törölgetnénk őket, ezzel elég látványos - és mély - nyomokat lehetne hagyni mindenkiben.

Címkék:Minecraft 2 komment

_fpeti_ 2011.10.08. 00:34

Egy régi-új npc

Első npc-met 3d-ben 'sonofapeach'-nek azaz 'barackfia'-nak neveztem el :). Elég hülyén nézett ki. Most 'elővettem a képességeimet', és Blenderben egy gömbből és egy pöfeteg gombáról készült fényképem segedelmével megalkottam a kettes verziót. Döntse el mindenki, mire hasonlít Elég gusztustalan, de szörnyes fps-ben talán nem olyan nagy gond az.

Amúgy a doom beli cacodemon ihlette, csak nem olyan lett.
(Csak tudnám hogy kell szebben beilleszteni képet)
ps: Ez még mindig placeholder, nem kell megijedni.


 

 

 

 

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

_fpeti_ 2011.09.22. 02:04

Képek

Blogolás gyakorlása céljából :)
Íme egy lyuk amiből felfelé fény jön (magmalight a neve).

 

Emissive texture:

 

 Water refraction: Avatott szeműek észrevehetik, hogy nem csak a víz alatti részeket torzítja, de nem sok kedvem van csak emiatt mégy egyszer renderelni. Nekem tetszik (ami nem sok jót szokott jelenteni.)

 

Szólj hozzá!

_fpeti_ 2011.07.30. 03:01

Ázekh!

DrawPrimitive()-el nem működik a HW instancing dx9-el! Majd 2 órám ment el mire kiderült, DrawIndexedPrimitive()-el egyből megy!

Jó tudni (nem annyira, de jó :) )

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

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