Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

61
Részecskerendszerek, spriteok, plakátok, instancing Szécsi László

Transcript of Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Page 1: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Részecskerendszerek, spriteok, plakátok,

instancing

Szécsi László

Page 2: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Eddig jutottunk….

Page 3: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Ú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

Page 4: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 5: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Próba

WASD + egér

Page 6: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

class Lab4Particles {LPDIRECT3DVERTEXBUFFER9 billboardVertexBuffer;LPDIRECT3DINDEXBUFFER9

billboardIndexBuffer;LPDIRECT3DVERTEXBUFFER9 particleInstanceBuffer;LPDIRECT3DVERTEXDECLARATION9 particleSystemVertexDecl;unsigned int nMaxParticles;

Plakát geometriaFILE Lab4Particles.hOP new member CLASS Lab4Particles

Page 7: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

class Particle

{

friend class Lab4Particles;

D3DXVECTOR3 pos;

D3DXVECTOR3 velocity;

float age[2];

};

Részecske classFILE Particle.h Particle.cppOP new class CLASS Particle

Page 8: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

#include "Particle.h"

Részecske classFILE Lab4Particles.cppOP new include CLASS Lab4Particles

Page 9: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Lab4Particles::Lab4Particles(

LPDIRECT3DDEVICE9 device)

:EngineInterface(device), nMaxParticles(20)

{

Maximum részecskeszám inticializálásaFILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD Lab4Particles

Page 10: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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() };

Page 11: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

device->CreateVertexDeclaration(

particleSystemVertexElements,

&particleSystemVertexDecl);

Vertex layout megadása folyt.FILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD createDefaultResources

Page 12: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

HRESULT Lab4Particles::

releaseDefaultResources()

{

particleSystemVertexDecl

->Release();

Vertex desc felszabadításaFILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD releaseDefaultResources

Page 13: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 14: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 15: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 16: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 17: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 18: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 19: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

HRESULT lab4Particles::

releaseDefaultResources(){

billboardVertexBuffer

->Release();

billboardIndexBuffer

->Release();

particleInstanceBuffer

->Release();

Bufferek felszabadításaFILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD releaseDefaultResources

Page 20: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 21: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 22: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 23: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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 ::

Page 24: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 25: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

float4 psParticle(

ParticleOutput input):COLOR

{

return input.color;

}

Pixel shaderFILE billboard.fxOP new func FUNC psParticle

Page 26: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

technique billboard{

pass ExamplePass

{

VertexShader = compile

vs_3_0 vsParticle();

PixelShader = compile

ps_2_0 psParticle();

}

}

Billboard techniqueFILE billboard.fxOP new technique FUNC ::

Page 27: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 28: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

class Lab4Particles

{

LPDIRECT3DTEXTURE9

particleTexture;

Részecske textúraFILE Lab4Particles.hOP new member CLASS Lab4Particles

Page 29: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

HRESULT Lab4Particles::

createManagedResources() {

D3DXCreateTextureFromFile(

device,

L"media//particle.dds",

&particleTexture);

Textúra betöltéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD releaseManagedResources

Page 30: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

HRESULT Lab4Particles::releaseManagedResources()

{

particleTexture->Release();

Textúra felszabadításaFILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD createManagedResources

Page 31: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

void Lab4Particles::render()

{

effect->SetTexture("colorMap",

particleTexture);effect->CommitChanges();

Textúra bekötéseFILE Lab4Particles.cppOP add code CLASS Lab4Particles

METHOD render

Page 32: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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 ::

Page 33: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

float4 psParticle(ParticleInput input):COLOR

{return input.color *

tex2D(colorMapSampler, input.tex);

}

Új textúra és samplerFILE billboard.fxOP edit code FUNC psParticle

Page 34: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 35: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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 ::

Page 36: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 37: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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 ::

Page 38: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 39: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 40: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 41: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 42: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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!

Page 43: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 44: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 45: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 46: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 47: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

PróbaWASD + egér

Page 48: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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 ::

Page 49: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

class Particle;

class Lab4Particles {

Particle* particles;

Részecske tömb rendszermemóriábanFILE Lab4Particles.hOP new member CLASS Lab4Particles

Page 50: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 51: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Lab4Particles::~Lab4Particles()

{

delete particles;

}

Részecske tömb allokálásFILE Lab4Particles.cppOP new method CLASS Lab4Particles

METHOD ~Lab4Particles

Page 52: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

class EngineInterface

{

virtual ~EngineInterface(){}

Ugye virtuális a destruktor?FILE EngineInterface.hOP verify code CLASS EngineInterface

METHOD ~EngineInterface

Page 53: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 54: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 55: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 56: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Próbahibás takarás

Page 57: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 58: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 59: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 60: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

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

Page 61: Részecskerendszerek, spriteok, plakátok, instancing Szécsi László.

Lab4Particles::Lab4Particles(

LPDIRECT3DDEVICE9 device)

:EngineInterface(device), nMaxParticles(200)

{

Több részecskeFILE Lab4Particles.cppOP edit code CLASS Lab4Particles

METHOD Lab4Particles