Plakátok, részecskerendszerek Szécsi László
Képalapú festés Montázs: képet képekből 2D grafika jellemző eszköze – modell: kép [sprite]
3D – 2D képével helyettesítsük a komplex geometriát – Image-based rendering
A sprite evolúciója C64 – 2D grafika – hardver támogatás: 8db 24x21-es bitmap kirakása adott pixelkoordinátákra – nincs elforgatás, skálázás – blitter: bit block transfer • sprite mem → frame buffer
A sprite evolúciója modern grafikus pipelineban – pont primitívek rajzolása [point sprite] – pont mérete [p×p pixeles négyzet]: • D3DRS_POINTSIZE
– pixel shaderben olvasható a kép mint textúra – Shader Model 4.0 • point sprite már nincs, mivel háromszögekkel is megoldható (minek foglalja a tranzisztorokat)
A sprite evolúciója 3D grafikában – a 2D sprite 3D geometriát helyettesít [impostor] – képernyőtérbeli quad, de • skálázható, mérete a távolság függvényében változhat • rendelhető hozzá mélység, z-teszt használható rá
– világkoordinátákban adott pozíció, méret, de mindig a kamera felé fordul
Sprite rajzolása klasszikus trafókkal a sprite modellje egy z irányba néző quad – a világban úgy forgatjuk a quadot, hogy a kamera fele nézzen – a kamera trafó forgatás részét “ki kell iktatni” – kamera trafó inverz transzponáltjával kell a quad vertexeit transzformálni – utána jöhet a kamera trafó és projekció
csak akkor van értelme ha a kamera trafó végrehajtásába nem tudunk belenyúlni
Sprite rajzolása klasszikus trafókkal modell trafóban nincs elforgatás mert a spritenak nincs orientációja
ez változatlan maradhat view elforgatás kiiktatása
sprite model trafó model eltolás
modellezési koordináták model space z irányba néző quad
temp. világkoordináták world space z irányba néző quad
proj trafó
view trafó
inverz tr. view trafó
világkoordináták world space
kamera koordináták camera space
norm. képernyő koordináták clip space norm. device space
kamera felé néző quad
z irányba néző quad
2D quad
Sprite rajzolása saját trafóval a modellezési origót [sprite középpontjának a pozícióját] transzformáljuk a kamera koodinátarendszerbe – kamera koordinátákban adjuk hozzá a csúcsok (spriteon belüli) pozícióit – utána jöhet a proj trafó
Sprite rajzolása saját trafóval kamera koordináták camera space
vertex shaderben a view trafó után adjuk hozzá a quad vertex pozíciókat
z irányba néző quad model trafó
proj trafó
view trafó
Σ modellezési koordináták model space 0,0,0
világkoordináták world space sprite pozíció
kamera koordináták camera space sprite pozíció
norm. képernyő koordináták clip space norm. device space 2D quad
Vertex shader sprite rajzolásra struct vsSpriteInput { float4 quadVertexPos: float2 tex : float3 spritePos : float age : }; struct vsSpriteOutput { float4 pos float2 tex float age }
TEXCOORD0; TEXCOORD1; POSITION; TEXCOORD2
: POSITION; : TEXCOORD0; : TEXCOORD1;
Vertex shader sprite rajzolásra vsSpriteOutput vsSprite(vsSpriteInput input) { float3 cameraSpritePos = mul(input.spritePos, viewMatrix); float3 cameraVertexPos = cameraSpritePos + input.quadVertexPos; output.pos = mul( float4(cameraVertexPos, 1), projMatrix); output.tex = input.tex; output.age = input.age; }
Plakát [billboard] sprite mindig teljesen a kamera fele néz a plakát is egy textúrázott quad – lehet statikus – foroghat 1 tengely körül – illeszkedhet felületre stb.
billboard általánosabb, mint a sprite
Statikus plakát 3D objektumok megjelenítésére önmagában gyenge, ha rossz irányból nézünk rá sok felületből már meggyőző modell lehet plakátfelhő [billboard cloud]
Tengely körül forgó plakát tipikus alkalmazás: fák
Részecske-rendszer térfogati jelenségek – pl. tűz, füst, köd, por, sugárhajtómű – bonyolult fizika, áramlás-szimuláció, NavierStokes difegyenlet helyett – szimuláljuk néhány részecske útját az áramlásban egyszerű szabályok alapján – jelenítsük meg őket mint felhőcskéket – áttetsző, textúrázott plakátokkal • billboard + blending + instancing [sok ugyanolyan geometria]
Részecskék életciklusa születés – emitter: pontszerű, vonalas, sík, térfogat
jellemzők – pozíció, sebesség, életkor, méret, szín, átlátszóság
hatások – effector: szél, felhajtóerő, turbulencia, gravitáció
halál
Bufferek LPDIRECT3DINDEXBUFFER9 billboardIndexBuffer; LPDIRECT3DVERTEXBUFFER9 billboardVertexBuffer;
alap geometria
LPDIRECT3DVERTEXBUFFER9 particleInstanceBuffer; példány adatok LPDIRECT3DVERTEXDECLARATION9 particleSystemVertexDecl; vertex layout
Részecske osztály class Particle { D3DXVECTOR3 pos; D3DXVECTOR3 velocity; float age; void move(double dt); ... };
Vertex layout D3DVERTEXELEMENT9 particleSystemVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4}, {1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, {1, 24, D3DDECLTYPE_FLOAT, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2}, D3DDECL_END() }; device->CreateVertexDeclaration( particleSystemVertexElements, &particleSystemVertexDecl);
quad
particle
Quad összerakása vertex buffer, index buffer létrehozása lock feltöltés unlock
Instance buffer device->CreateVertexBuffer( sizeof(Particle) * nMaxParticles, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &particleInstanceBuffer, NULL);
Rajzolás instancinggel device->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | nParticles); device->SetStreamSource(0, billboardVertexBuffer, 0, sizeof(float) * 5); device->SetIndices(billboardIndexBuffer);
ennyi példány ebből
device->SetStreamSourceFreq( 1, (unsigned)(D3DSTREAMSOURCE_INSTANCEDATA | 1)); device->SetStreamSource(1, particleInstanceBuffer, példányonkénti 0, sizeof(Particle)); adatok device->SetVertexDeclaration(particleSystemVertexDecl); device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2); device->SetStreamSourceFreq(0, 1); device->SetStreamSource(1, NULL, 0, 0);
vertex shaderbe melyik bufferből honnan jön a paraméter