420 likes | 571 Views
Pipeline. Vertex shader. Fragment shader. Transzformációs modul. A modellünket a saját koordinátarendszerében adjuk meg Azonban a saját koordinátarendszerükben lévő modelleket egy közös, úgynevezett világ koordinátarendszerbe kell hozni
E N D
Pipeline Vertex shader Fragment shader
Transzformációs modul • A modellünket a saját koordinátarendszerében adjuk meg • Azonban a saját koordinátarendszerükben lévő modelleket egy közös, úgynevezett világ koordinátarendszerbe kell hozni • Ezt különböző transzformációkkal – nagyítás, kicsinyítés, forgatás, eltolás – visszük végbe
Transzformációs modul • Először közös koordinátarendszerbe helyezzük a színtér alkotóelemeit - ez a világ transzformáció • Utána az aktuális nézőpontunknak megfelelően tovább transzformálódik a színtér - ez a nézet transzformáció • Végül pedig létrejön a 3D-s színterünk 2D-s vetülete - ez a vetítési transzformáció
Transzformációs modul • A transzformációs modul a fenti transzformációkat vektor-mátrix szorzásokkal valósítja meg • A szorzásokat a DirectX végzi, nekünk FFP-nél csak meg kell mondani neki, hogy egy-egy konkrét transzformációt mely mátrixok valósítják meg • Shaderekben pedig el kell végezni a szorzást a mul CG paranccsal
Transzformációk • A transzformációkat 4x4-es mátrixokkal adjuk meg • A D3DX utility könyvtárban két megvalósítás is van (az alap D3DMATRIX-on kívül) ezeknek: • D3DXMATRIX • D3DXMATRIXA16: a memóriába 16 bájtos egységekre illeszti a mátrixokat – ezt az Intel procik szeretik, sokat lendít a sebességen
Transzformációk • Bármely affin transzformáció A mátrixa felírható egy N nyírás, egy S léptékezés, egy O origó körüli elforgatás és egy T eltolás mátrix szorzataként • Figyeljünk azonban a sorrendre: • A DirectX a mátrix-vektorszorzást balról jobbra végzi • Vagyis a transzformált x’ pontot így kapjuk: x’=xA
Transzformációk • Ezt mindenképpen jegyezzük meg, ugyanis általában a következőt szeretnénk csinálni a világban való elhelyezés során: • Nagyítani/kicsinyíteni a modellünket • Elforgatni a modellünket (orientációt beállítani) • Eltolni a modellünket a helyére a világban
Világtranszformáció • A modell saját koordinátarendszeréből a világ koordinátarendszerbe térünk át
D3DX utility könyvtár • A transzformációk mátrixát a D3DX függvényeinek segítségével állítjuk elő • A következő lib és header fájlokra lesz szükség hozzájuk:#pragmacomment(lib,"d3dx9.lib")#include <d3dx9.h>
Mátrixműveletek • D3DXMATRIX * D3DXMatrixIdentity( D3DXMATRIX * pOut ); • A paraméterben kapott címen lévő mátrixot a 4x4-es egységmátrixszal tölti fel • D3DXMATRIX m_id;D3DXMatrixIdentity(&m_id);
Mátrixműveletek • D3DXMATRIX * D3DXMatrixMultiply( D3DXMATRIX * pOut, CONST D3DXMATRIX * pM1, CONST D3DXMATRIX * pM2 ); • Az első paraméterben kapott címre kerül a második és harmadik helyen kapott mátrixok szorzata (balról jobbra szoroz) • Előbb az M1, aztán az M2 transzformációt elvégző mátrix lesz az eredmény • A D3DXMATRIX ‘*’ operátorát is használhatjuk
Mátrixműveletek • D3DXMATRIX* D3DXMatrixRotationX( D3DXMATRIX* pOut, FLOAT Angle); • Az első paraméterben kapott mátrixot feltölti az X tengely körüli Angle radián nagyságú elforgatás mátrixával • D3DXMatrixRotationY, D3DXMatrixRotationZ hasonló
Mátrixműveletek • D3DXMATRIX * D3DXMatrixRotationYawPitchRoll( D3DXMATRIX * pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); • Forgatásmátrixot készít, ami az Y tengely körül Yaw, az X körül Pitch, a Z körül pedig Roll szöggel forgat el
Mátrixműveletek • D3DXMATRIX * D3DXMatrixTranslation( D3DXMATRIX * pOut, FLOAT x, FLOAT y, FLOAT z ); • A paraméterben kapott mátrixot az (x,y,z) vektorral való eltolás mátrixa lesz
Mátrixműveletek • D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); • Balsodrású projekciós mátrixot épít, paramétereit lásd később
Mátrix-vektor műveletek • D3DXVECTOR4* D3DXVec3Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM); • A pV vektor homogén alakját transzformálja a pM mátrixszal • Az eredmény 4 komponensű vektor lesz
Mátrix-vektor műveletek • D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM); • A pV vektor homogén alakját transzformálja a pM mátrixszal • Az eredmény a homogén osztás utáni, w koordináta elhagyásával kapott vektor lesz
Vetítési transzformáció • Tekinthetünk rá úgy, mint a kamera belső tulajdonságainak beállítására • Mi most egy perspektív transzformációt fogunk beállítani
D3DXMatrixPerspectiveFovLH • D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); • pOut: kimeneti mátrix
D3DXMatrixPerspectiveFovLH • D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); • fovy: radiánban mért látószög
D3DXMatrixPerspectiveFovLH • D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); • Aspect: a nézetmező szélesség:magasság aránya
D3DXMatrixPerspectiveFovLH • D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); • zn: közelsík távolsága, >0
D3DXMatrixPerspectiveFovLH • D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); • zf: távolsík távolsága
Nézet transzformáció • Azt szeretnénk, hogy ne egy, vagy néhány adott objektum helyzete változzon, hanem az a hely, ahonnan nézzük a színteret • Erre szolgál a nézeti transzformáció, elhelyezi a virtuális világban a szemlélőt • D3DXMatrixLookAtLH: balsodrású koordinátarendszer nézeti transzformációját állítja elő nézőpont, nézett pont és felfelé mutató irány alapján
Nézet transzformáció Z vLookatPt vUpVec vEyePt Y X
VOID CDXMyApp::Render() VOID CDXMyApp::Render() { ... m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0),1.0f,0); ...
Z-buffer • Az ősosztályba bekerült D3DPRESENT_PARAMETERS struktúra feltöltésében is meg kell erről emlékeznünk: • DXAppBase.cpp: ... m_d3dpp.EnableAutoDepthStencil = TRUE; m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; ...
Z-buffer • A backbuffer felbontásának megfelelő nagyságú lesz • Egy-egy eleme ( (x,y) pontbeli értéke) azt mondja meg, hogy az adott pixelben látható fragment milyen messze van
Culling • A DirectX alapbeállítás szerint a hátrafelé néző lapokat nem veszi figyelembe rendereléskor • Tehát amikor körbeforog a négyzetünk, az esetek felében nem látszik majd ha ezt így hagyjuk
Előre néző lap • Egy háromszög előre néző lapja (front face) megkapható, ha ismerjük a háromszög 3 csúcspontját • Egy háromszög előre néző lapja (front face) az, amelyiknek a normálvektora felől nézve a háromszög csúcsai az óra járásával megegyező irányban adottak a primitívmegadáskor
IDirect3DDevice9::SetRenderState • HRESULT SetRenderState( D3DRENDERSTATETYPE State, DWORD Value ); • State: melyik állapot beállításait akarjuk módosítani. Lehet például D3DRS_FILLMODE, D3DRS_LIGHTING, D3DRS_CULLMODE, stb. (Ld. D3DRENDERSTATETYPE)
IDirect3DDevice9::SetRenderState • HRESULT SetRenderState( D3DRENDERSTATETYPE State, DWORD Value ); • Value: az állapotváltozó új értéke. D3DRS_CULLMODE-nál ez lehet: • D3DCULL_NONE: nincs eldobás • D3DCULL_CW: óramutató járása szerint • D3DCULL_CCW: azzal ellentétesen