Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.
-
Upload
darius-trim -
Category
Documents
-
view
217 -
download
1
Transcript of Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.
Részecskerendszerek, spriteok, plakátok,
instancing
Szécsi László
Eddig jutottunk….
Új osztály: Lab4Particles
copy&paste: Lab3EnvMap.h ->
Lab4Particles.h
copy&paste: Lab3EnvMap.cpp ->
Lab4Particles.cpp
search&replace ebben a két fileban:Lab3EnvMap->Lab4Particles
copy&paste: envmap.fx -> billboard.fx
Effect betöltésnél: billboard.fx
Lab3 példány helyett Lab4 példányt hozzunk létre
#include “Lab4Particles.h”
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ){
engine = new Lab3EnvMap(pd3dDevice);engine = new Lab4Particles(pd3dDevice);
Globális példány kicseréléseFILE GraphGame.cppOP del/add code FUNC OnD3D9CreateDevice
Próba
WASD + egér
class Lab4Particles {LPDIRECT3DVERTEXBUFFER9 billboardVertexBuffer;LPDIRECT3DINDEXBUFFER9
billboardIndexBuffer;LPDIRECT3DVERTEXBUFFER9 particleInstanceBuffer;LPDIRECT3DVERTEXDECLARATION9 particleSystemVertexDecl;unsigned int nMaxParticles;
Plakát geometriaFILE Lab4Particles.hOP new member CLASS Lab4Particles
class Particle
{
friend class Lab4Particles;
D3DXVECTOR3 pos;
D3DXVECTOR3 velocity;
float age[2];
};
Részecske classFILE Particle.h Particle.cppOP new class CLASS Particle
#include "Particle.h"
Részecske classFILE Lab4Particles.cppOP new include CLASS Lab4Particles
Lab4Particles::Lab4Particles(
LPDIRECT3DDEVICE9 device)
:EngineInterface(device), nMaxParticles(20)
{
Maximum részecskeszám inticializálásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD Lab4Particles
Vertex layout megadásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
HRESULT Lab4Particles::createDefaultResources() {
D3DVERTEXELEMENT9 particleSystemVertexElements[] ={
{0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_TEXCOORD, 0},
{1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
{1, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
D3DDECL_END() };
device->CreateVertexDeclaration(
particleSystemVertexElements,
&particleSystemVertexDecl);
Vertex layout megadása folyt.FILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
HRESULT Lab4Particles::
releaseDefaultResources()
{
particleSystemVertexDecl
->Release();
Vertex desc felszabadításaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD releaseDefaultResources
HRESULT Lab4Particles::createDefaultResources(){device->CreateVertexBuffer(
4 * sizeof(D3DXVECTOR4),D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,D3DFVF_XYZW,D3DPOOL_DEFAULT,&billboardVertexBuffer,NULL);
Billboard vertex buffer létrehozásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
D3DXVECTOR4* vertexData;billboardVertexBuffer->Lock(0, 0, (void**)&vertexData,
D3DLOCK_DISCARD);
//float4(offset.x, offset.y, texcoord.u, texcoord.v)vertexData[0] = D3DXVECTOR4(-1.0f, -1.0f, 0.0f, 0.0f);vertexData[1] = D3DXVECTOR4(1.0f, -1.0f, 1.0f, 0.0f);vertexData[2] = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);vertexData[3] = D3DXVECTOR4(-1.0f, 1.0f, 0.0f, 1.0f);
billboardVertexBuffer->Unlock();
Billboard vertex buffer feltöltéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
device->CreateIndexBuffer(
6 * sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,
&billboardIndexBuffer,
NULL);
Index vertex buffer létrehozásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
short* indexData;billboardIndexBuffer->Lock(0, 0, (void**)&indexData, D3DLOCK_DISCARD);indexData[0] = 0;indexData[1] = 3;indexData[2] = 1;indexData[3] = 2;indexData[4] = 1;indexData[5] = 3;billboardIndexBuffer->Unlock();
Index vertex buffer feltöltéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
device->CreateVertexBuffer(
sizeof(Particle) *
nMaxParticles,
D3DUSAGE_DYNAMIC, 0,
D3DPOOL_DEFAULT,
&particleInstanceBuffer,
NULL);
Példány adatok buffere (instance buffer)FILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
Particle* particleData;particleInstanceBuffer->Lock(0, 0, (void**)&particleData, D3DLOCK_DISCARD);for(int i = 0; i < nMaxParticles; i++) { float x = (float)rand() / RAND_MAX * 20; float y = (float)rand() / RAND_MAX * 20; float z = (float)rand() / RAND_MAX * 20; particleData[i].pos =
D3DXVECTOR3(x, y, z);}particleInstanceBuffer->Unlock();
Példány adatok feltöltéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
HRESULT lab4Particles::
releaseDefaultResources(){
billboardVertexBuffer
->Release();
billboardIndexBuffer
->Release();
particleInstanceBuffer
->Release();
Bufferek felszabadításaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD releaseDefaultResources
effect->EndPass();
effect->End();
effect->
SetTechnique("billboard");
effect->Begin(&a, 0);
effect->BeginPass(0);
Technique beállítás rajzoláshozFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD render
device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA |
nMaxParticles);device->SetStreamSource
(0, billboardVertexBuffer, 0, sizeof(float) * 4);
device->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA | 1);
device->SetStreamSource(1, particleInstanceBuffer, 0,
sizeof(Particle));device->SetVertexDeclaration
(particleSystemVertexDecl);device->SetIndices(billboardIndexBuffer);
Bufferek inputra kötéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD render
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
device->SetStreamSourceFreq(0, 1);device->SetStreamSource(0, NULL, 0, 0);device->SetStreamSourceFreq(1, 1);device->SetStreamSource(1, NULL, 0, 0);device->SetIndices(0);
effect->EndPass();effect->End();
Rajzolás és az instancing kikapcsolásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD render
struct ParticleInput{ float4 pos : POSITION; float4 offset : TEXCOORD0; float3 velocity : TEXCOORD1; float2 age : TEXCOORD2;};
struct ParticleOutput{ float4 pos : POSITION; float2 tex : TEXCOORD0; float4 color : TEXCOORD1; };
Input-output szemantikaFILE billboard.fxOP new struct FUNC ::
float2 billboardSize = float2(5, 5);ParticleOutput vsParticle(
ParticleInput input) {ParticleOutput output = (ParticleOutput) 0;output.pos = mul(input.pos,
modelViewProjMatrix);output.pos.xy +=
input.offset.xy * billboardSize;output.tex = input.offset.zw;output.color = 1;return output;}
Vertex shaderFILE billboard.fxOP new func FUNC vsParticle
float4 psParticle(
ParticleOutput input):COLOR
{
return input.color;
}
Pixel shaderFILE billboard.fxOP new func FUNC psParticle
technique billboard{
pass ExamplePass
{
VertexShader = compile
vs_3_0 vsParticle();
PixelShader = compile
ps_2_0 psParticle();
}
}
Billboard techniqueFILE billboard.fxOP new technique FUNC ::
PróbaWASD + egér
class Lab4Particles
{
LPDIRECT3DTEXTURE9
particleTexture;
Részecske textúraFILE Lab4Particles.hOP new member CLASS Lab4Particles
HRESULT Lab4Particles::
createManagedResources() {
D3DXCreateTextureFromFile(
device,
L"media//particle.dds",
&particleTexture);
Textúra betöltéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD releaseManagedResources
HRESULT Lab4Particles::releaseManagedResources()
{
particleTexture->Release();
Textúra felszabadításaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createManagedResources
void Lab4Particles::render()
{
effect->SetTexture("colorMap",
particleTexture);effect->CommitChanges();
Textúra bekötéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD render
texture colorMap;sampler2D colorMapSampler =
sampler_state{texture = < colorMap >;MinFilter = LINEAR;MagFilter = LINEAR;MipFilter = LINEAR;AddressU = Wrap;AddressV = Wrap;};
Új textúra és samplerFILE billboard.fxOP new var FUNC ::
float4 psParticle(ParticleInput input):COLOR
{return input.color *
tex2D(colorMapSampler, input.tex);
}
Új textúra és samplerFILE billboard.fxOP edit code FUNC psParticle
PróbaWASD + egér
technique billboard{
pass ExamplePass{
AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
ZWriteEnable = false;
VertexShader = compile
vs_3_0 vsParticle();
PixelShader = compile
ps_2_0 psParticle();
}
}
Alpha blendingFILE billboard.fxOP edit script FUNC ::
PróbaWASD + egér
technique billboard{ pass ExamplePass{
AlphaBlendEnable = true;SrcBlend = SrcAlpha;DestBlend = One;ZWriteEnable = false;VertexShader = compile
vs_3_0 vsParticle(); PixelShader = compile
ps_2_0 psParticle(); }}
Additive blendingFILE billboard.fxOP edit code FUNC ::
PróbaWASD + egér
float4 psParticle(
ParticleOutput input):COLOR {
float4 color = input.color *
tex2D(colorMapSampler,
input.tex);
color.rgb =
float3(color.a,
pow(color.a, 4),
pow(color.a, 10));
return color; }
Játsszunk a színekkelFILE billboard.fxOP edit code FUNC psParticle
PróbaWASD + egér
class Particle {void reborn() { float x = (float)rand() / RAND_MAX; float y = (float)rand() / RAND_MAX; float z = (float)rand() / RAND_MAX; x = x * 2 - 1; y = y * 2 - 1; z = z * 2 - 1; pos = D3DXVECTOR3(x, y, z); age[0] = 0; age[1] = 2.0 + (float)rand()
/ RAND_MAX * 3.0;velocity = D3DXVECTOR3(x*5, y*5, z*5);}
Részecske születésFILE Particle.hOP new method CLASS Particle
METHOD reborn
HRESULT Lab4Particles::
createDefaultResources() {
for(int i = 0; i < nMaxParticles; i++)
{
particleData[i].reborn();
}
Részecskék inicializálásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD createDefaultResources
gy.k.: ami szürke, azt nem kell még egyszer bemásolni!
class Particle{void move(float dt)
{pos = pos +
velocity * dt;age[0] += dt;if(age[0] > age[1])
reborn();}
Részecske animációFILE Particle.hOP new method CLASS Particle
METHOD move
void Lab4Particles::animate(double dt, double t){ camera.FrameMove(dt);void* instanceData;particleInstanceBuffer-> Lock (0, 0, &instanceData, 0);Particle* particleData =
(Particle*) instanceData;
for(int i = 0; i < nMaxParticles; i++)particleData[i].move(dt);
particleInstanceBuffer->Unlock();}
Részecskerendszer animációFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD animate
PróbaWASD + egér
float2 billboardSize = float2(5.0, 5.0);ParticleOutput vsParticle(ParticleInput input) { ParticleOutput output = (ParticleOutput) 0; output.pos = mul(input.pos, modelViewProjMatrix);
float relAge = input.age[0] /input.age[1];
output.pos.xy += input.offset.xy *billboardSize * 6.0 * relAge;
output.color = 1 - abs(relAge * 2.0 - 1.0);
output.tex = input.offset * 0.5 + float2(0.5, 0.5); return output; }
Korfüggő méret, intenzitás és átlátszóságFILE billboard.fxOP edit code FUNC vsParticle
PróbaWASD + egér
technique billboard{
pass ExamplePass{
AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
ZWriteEnable = false;
VertexShader = compile
vs_3_0 vsParticle();
PixelShader = compile
ps_2_0 psParticle();
}
}
Alpha blending visszaállításaFILE billboard.fxOP edit script FUNC ::
class Particle;
class Lab4Particles {
Particle* particles;
Részecske tömb rendszermemóriábanFILE Lab4Particles.hOP new member CLASS Lab4Particles
Lab4Particles::Lab4Particles(LPDIRECT3DDEVICE9 device)
:EngineInterface(device), nMaxParticles(20) {
particles = new
Particle[nMaxParticles];
for(int i = 0;
i < nMaxParticles; i++)
particles[i].reborn();
Részecske tömb allokálásFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD Lab4Particles
Lab4Particles::~Lab4Particles()
{
delete particles;
}
Részecske tömb allokálásFILE Lab4Particles.cppOP new method CLASS Lab4Particles
METHOD ~Lab4Particles
class EngineInterface
{
virtual ~EngineInterface(){}
Ugye virtuális a destruktor?FILE EngineInterface.hOP verify code CLASS EngineInterface
METHOD ~EngineInterface
Particle* particleData;
particleInstanceBuffer->Lock(0, 0, (void**)&particleData, D3DLOCK_DISCARD);
for(int i = 0; i < nMaxParticles; i++) {
float x = (float)rand() / RAND_MAX * 20;
float y = (float)rand() / RAND_MAX * 20;
float z = (float)rand() / RAND_MAX * 20;
particleData[i].pos =
D3DXVECTOR3(x, y, z);
particleData[i].reborn();
}
particleInstanceBuffer->Unlock();
Instance buffer init törlésFILE Lab4Particles.cppOP delete code CLASS Lab4Particles
METHOD createDefaultResources
void* instanceData;
particleInstanceBuffer->
Lock (0, 0, &instanceData, 0);
Particle* particleData =
(Particle*) instanceData;
for(int i = 0; i < nMaxParticles; i++)
particleData[i].move(dt);
particleInstanceBuffer->Unlock();
Instance bufferben közvetlen anim törlésFILE Lab4Particles.cppOP delete code CLASS Lab4Particles
METHOD animate
for(int i = 0; i < nMaxParticles; i++)particles[i].move(dt);
//ide jön a rendezésvoid* instanceData;particleInstanceBuffer->Lock(0, 0,
&instanceData, 0);memcpy(instanceData, particles,
sizeof(Particle) *nMaxParticles);
particleInstanceBuffer->Unlock();
Tömb animációja, feltöltéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD animate
Próbahibás takarás
const D3DXVECTOR3& ahead = *camera.GetWorldAhead();
for(int j = 1; j < nMaxParticles; j++)
for(int k = 0; k < nMaxParticles-1; k++) {
float distk = D3DXVec3Dot(&ahead,
&particles[k].pos);
float distk1 = D3DXVec3Dot(&ahead,
&particles[k+1].pos);
if( distk < distk1) {
Particle p = particles[k+1];
particles[k+1] = particles[k];
particles[k] = p;
}
}
Buborékrendezés kamera z szerintFILE Lab4Particles.cppOP add code CLASS Lab4Particles
METHOD animate
float4 psParticle(ParticleOutput input):COLOR {
float4 color =
tex2D(colorMapSampler, input.tex);
color.rgb = float3(color.a,
pow(color.a, 4),
pow(color.a, 10));
return float4(color.rgb, color.a
* input.color.a); }
Életkorfüggő sötétedés ne legyenFILE billboard.fxOP edit code FUNC psParticle
Próba
most már jó a sorrend, de ha változik, hirtelen váltás van
(popping)
megoldás: elvi szinten nincs
enyhítés:
több halványabb billboard
float4 color =
tex2D(colorMapSampler, input.tex);
color.rgb = float3(color.a,
pow(color.a, 4),
pow(color.a, 10));
return float4(color.rgb, color.a * input.color.a * 0.1);
HalványításFILE billboard.fxOP edit code FUNC psParticle
Lab4Particles::Lab4Particles(
LPDIRECT3DDEVICE9 device)
:EngineInterface(device), nMaxParticles(200)
{
Több részecskeFILE Lab4Particles.cppOP edit code CLASS Lab4Particles
METHOD Lab4Particles