graphgame gg0 1 1-particles

61
GraphGame gg011-Particles Plakátok, részecskerendszerek Szécsi László

Upload: forbes

Post on 23-Feb-2016

38 views

Category:

Documents


0 download

DESCRIPTION

GraphGame gg0 1 1-Particles. Plakátok, részecskerendszerek Szécsi László. gg0 1 1-Particles project. copy-paste-rename gg00 9 - Gui folder (sok zsiráf nem kell ide) vcxproj , filters átnevezés solution /add existing project rename project working dir: $( SolutionDir ) - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: GraphGame gg0 1 1-Particles

GraphGamegg011-Particles

Plakátok, részecskerendszerek

Szécsi László

Page 2: GraphGame gg0 1 1-Particles

gg011-Particles project

• copy-paste-rename gg009-Gui folder (sok zsiráf nem kell ide)

• vcxproj, filters átnevezés• solution/add existing project• rename project• working dir: $(SolutionDir)• Project Properties/Configuration

Properties/Debugging/Command Arguments--solutionPath:"$(SolutionDir)" --projectPath:"$(ProjectDir)"

• build, run

Page 3: GraphGame gg0 1 1-Particles

Particle osztály#include "Math/math.h"class Particle{ friend class Game; Egg::Math::float3 position; Egg::Math::float3 velocity; float lifespan; float age;public:};

Page 4: GraphGame gg0 1 1-Particles

Particle osztályvoid reborn() { using namespace Egg::Math; position = float3::random(-1,1); velocity = position * 5; age = 0; lifespan = float1::random(2,5);}Particle(){ reborn(); }

Page 5: GraphGame gg0 1 1-Particles

Particle buffer, input layout és pass

• Lehetne ezeket kézzel létrehozni– ugyanúgy, ahogy a háromszögrajzolásnál az elején– csak a shader az effect fileból jön

• D3DX11_PASS_DESC billboardPassDesc;• effect->GetTechniqueByName("billboard")-> GetPassByName("fire")-

>GetDesc(&billboardPassDesc);– és a VB használati módja dinamikus– rajzoláskor

• context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);

• effect->GetTechniqueByName("billboard")-> GetPassByName("fire")->Apply(0, context);

• context->Draw(particles.size(), 0);

Page 6: GraphGame gg0 1 1-Particles

Egg::Mesh-t használva

• Mesh::VertexStream a buffer• Effect pass-ra Mesh::Material• InputLayout gyártása a Mesh::Binder feladata• a végén kapunk egy Mesh::Shaded-et amit

csak ki kell rajzolni– beállítja az effect pass-t– az input layoutot– a vertex buffert– rajzol

Page 7: GraphGame gg0 1 1-Particles

Game.h#include "Particle.h"#include <vector>

Page 8: GraphGame gg0 1 1-Particles

Game.hclass Game : public Egg::Sas::SasApp

{ std::vector<Particle> particles; Egg::Mesh::Shaded::P fireBillboardSet;

Page 9: GraphGame gg0 1 1-Particles

createResourcesfor(int i=0; i<40; i++) particles.push_back(Particle());

Page 10: GraphGame gg0 1 1-Particles

createResourcesD3D11_INPUT_ELEMENT_DESC particleElements[3];particleElements[0].AlignedByteOffset = offsetof(Particle, position);particleElements[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;particleElements[0].InputSlot = 0;particleElements[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;particleElements[0].InstanceDataStepRate = 0;particleElements[0].SemanticIndex = 0;particleElements[0].SemanticName = "POSITION";particleElements[1].AlignedByteOffset = offsetof(Particle, lifespan);particleElements[1].Format = DXGI_FORMAT_R32_FLOAT;particleElements[1].InputSlot = 0;particleElements[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;particleElements[1].InstanceDataStepRate = 0;particleElements[1].SemanticIndex = 0;particleElements[1].SemanticName = "LIFESPAN";particleElements[2].AlignedByteOffset = offsetof(Particle, age);particleElements[2].Format = DXGI_FORMAT_R32_FLOAT;particleElements[2].InputSlot = 0;particleElements[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;particleElements[2].InstanceDataStepRate = 0;particleElements[2].SemanticIndex = 0;particleElements[2].SemanticName = "AGE";

Page 11: GraphGame gg0 1 1-Particles

createResourcesEgg::Mesh::VertexStreamDesc particleBufferDesc;

particleBufferDesc.elements = particleElements;particleBufferDesc.nElements = 3;particleBufferDesc.nVertices = particles.size();particleBufferDesc.vertexStride = sizeof(Particle);

particleBufferDesc.vertexData = &particles.at(0);

particleBufferDesc.cpuAccessFlags = D3D11_CPU_ACCESS_WRITE;

particleBufferDesc.usage = D3D11_USAGE_DYNAMIC;

Page 12: GraphGame gg0 1 1-Particles

createResourcesEgg::Mesh::VertexStream::P particleVertexStream = Egg::Mesh::VertexStream::create( device, particleBufferDesc);

Page 13: GraphGame gg0 1 1-Particles

createResourcesID3DX11EffectPass* billboardPass = effect-> GetTechniqueByName("billboard")-> GetPassByName("fire");Egg::Mesh::Material::P fireMaterial = Egg::Mesh::Material::create( billboardPass, 0);fireBillboardSet = binder->bindMaterial( fireMaterial, particleVertexStream);

Page 14: GraphGame gg0 1 1-Particles

releaseResourcesfireBillboardSet.reset();

Page 15: GraphGame gg0 1 1-Particles

renderfireBillboardSet->draw(context);

Page 16: GraphGame gg0 1 1-Particles

Új fx file

• solution fx folderbe• billboard.fx

Page 17: GraphGame gg0 1 1-Particles

fx/main.fx#include <envmapped.fx>#include <billboard.fx>

#9.0

Page 18: GraphGame gg0 1 1-Particles

fx/billboard.fxstruct IaosBillboard{ float3 pos : POSITION; float lifespan : LIFESPAN; float age : AGE;};

typedef IaosBillboard VsosBillboard;

VsosBillboard vsBillboard(IaosBillboard input){ return input;}

#9.0

Page 19: GraphGame gg0 1 1-Particles

fx/billboard.fxstruct GsosBillboard{ float4 pos : SV_Position; float2 tex : TEXCOORD;};

float billboardWidth = 0.1;float billboardHeight = 0.1;

#9.0

Page 20: GraphGame gg0 1 1-Particles

fx/billboard.fx[maxvertexcount(4)]void gsBillboard( point VsosBillboard input[1], inout TriangleStream<GsosBillboard> stream) { float4 hndcPos = mul(float4(input[0].pos, 1), modelViewProjMatrix); GsosBillboard output; output.pos = hndcPos; output.pos.x += billboardWidth; output.pos.y += billboardHeight; output.tex = float2(1, 0); stream.Append(output);output.pos = hndcPos;output.pos.x += billboardWidth;output.pos.y -= billboardHeight;output.tex = float2(1, 1);stream.Append(output);output.pos = hndcPos;output.pos.x -= billboardWidth;output.pos.y += billboardHeight;output.tex = float2(0, 0);stream.Append(output);output.pos = hndcPos;output.pos.x -= billboardWidth;output.pos.y -= billboardHeight;output.tex = float2(0, 1);stream.Append(output); }

#9.0

Page 21: GraphGame gg0 1 1-Particles

fx/billboard.fxfloat4 psFire(GsosBillboard input) : SV_Target{ return input.tex.xyyy;}technique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); }}

#9.0

Page 22: GraphGame gg0 1 1-Particles

Színes plakátok

Page 23: GraphGame gg0 1 1-Particles

Textúra

• particle.dds letöltése• Projects/gg011-Particles/Media folderbe

Page 24: GraphGame gg0 1 1-Particles

Game classclass Game : public Egg::Sas::SasApp

{

ID3D11ShaderResourceView* billboardSrv;

Page 25: GraphGame gg0 1 1-Particles

createResourcesD3DX11CreateShaderResourceViewFromFileA( device, systemEnvironment.resolveMediaPath( "particle.dds" ).c_str(), NULL, NULL, &billboardSrv, NULL);effect-> GetVariableByName("billboardTexture") ->AsShaderResource(billboardSrv);

Page 26: GraphGame gg0 1 1-Particles

releaseResourcesbillboardSrv->Release();

Page 27: GraphGame gg0 1 1-Particles

fx/billboard.fxTexture2D billboardTexture;

float4 psFire(GsosBillboard input) : SV_Target{ return billboardTexture.Sample( linearSampler, input.tex.xy);}

#9.0

Page 28: GraphGame gg0 1 1-Particles

Textúrázott, de viewporthoz torzuló

Page 29: GraphGame gg0 1 1-Particles

createSwapChainResourcesusing namespace Egg::Math;

float4 worldBillboardSize(0.2, 0.2, 0, 0);float4 screenBillboardSize = worldBillboardSize * firstPersonCam->getProjMatrix();

effect-> GetVariableByName("billboardWidth")-> AsScalar()-> SetFloat(screenBillboardSize.x);effect-> GetVariableByName("billboardHeight")-> AsScalar()-> SetFloat(screenBillboardSize.y);

Page 30: GraphGame gg0 1 1-Particles

Állandó méretű plakátok

Page 31: GraphGame gg0 1 1-Particles

Alpha blending

• BlendState-et kell definiálni, pass-ban kiválasztani

• a többi pass-ban viszont vissza kéne állítani• legyen a blendStates.fx, amibe az összes

BlendState-et gyűjtjük• legyen akkor már– rasterizerStates.fx– depthStencilStates.fx

Page 32: GraphGame gg0 1 1-Particles

fx/blendStates.fxBlendState defaultBlender{};

BlendState additiveBlender{BlendEnable[0] = true;SrcBlend = src_alpha;DestBlend = one;BlendOp = add;SrcBlendAlpha = one;DestBlendAlpha = one;BlendOpAlpha = add;

};

#9.0

Page 33: GraphGame gg0 1 1-Particles

fx/blendStates.fxRasterizerState defaultRasterizer{};

RasterizerState noCullRasterizer{

CullMode = none;FillMode = solid;

};

RasterizerState backfaceRasterizer{

CullMode = front;FillMode = solid;

};

RasterizerState wireframeRasterizer{

CullMode = none;FillMode = wireFrame;

};

#9.0

Page 34: GraphGame gg0 1 1-Particles

depthStencilStates.fxDepthStencilState defaultCompositor{};

DepthStencilState noDepthTestCompositor{

DepthEnable = false;DepthWriteMask = zero;

};

DepthStencilState noDepthWriteCompositor{ DepthEnable = true; DepthWriteMask = zero;};

#9.0

Page 35: GraphGame gg0 1 1-Particles

fx/basic.fx#include <blendStates.fx>#include <rasterizerStates.fx>#include <depthStencilStates.fx>

...

technique11 basic{

pass basic{ SetVertexShader ( CompileShader( vs_5_0, vsTrafo() ) ); SetGeometryShader( NULL ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psBasic() ) ); SetDepthStencilState( defaultCompositor, 0 ); SetBlendState( defaultBlender,

float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }

}

#9.0

Page 36: GraphGame gg0 1 1-Particles

Minden pass legyen teljes

• textured/textured• shaded/diffuse, shaded/specular• envmapped/envmapped,

envmapped/background

Page 37: GraphGame gg0 1 1-Particles

fx/billboard.fxtechnique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); SetDepthStencilState( defaultCompositor, 0 ); SetBlendState( defaultBlender, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }}

#9.0

Page 38: GraphGame gg0 1 1-Particles

Ugyanaz

Page 39: GraphGame gg0 1 1-Particles

fx/billboard.fxtechnique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); SetDepthStencilState( defaultCompositor, 0 ); SetBlendState( additiveBlender, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }}

#9.0

Page 40: GraphGame gg0 1 1-Particles

Blending van… de z-teszt is

Page 41: GraphGame gg0 1 1-Particles

fx/billboard.fxtechnique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); SetDepthStencilState( noDepthTestCompositor, 0 ); SetBlendState( additiveBlender, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }}

#9.0

Page 42: GraphGame gg0 1 1-Particles

Nem depth test – zsiráf sem takar

Page 43: GraphGame gg0 1 1-Particles

fx/billboard.fxtechnique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); SetDepthStencilState( noDepthWriteCompositor, 0 ); SetBlendState( additiveBlender, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }}

#9.0

Page 44: GraphGame gg0 1 1-Particles

Zsiráf takar, plakát nem

Page 45: GraphGame gg0 1 1-Particles

fx/billboard.fxtechnique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); SetDepthStencilState( noDepthWriteCompositor, 0 ); SetBlendState( transparencyBlender, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }}

#9.0

Page 46: GraphGame gg0 1 1-Particles

Rossz a sorrend… hátsók takarnak előbbiekre

Ehhez rendezni kellene a plakátokat mélység szerint…

egyelőre inkább vissza az additívhoz!

Page 47: GraphGame gg0 1 1-Particles

Legyen színesebbfloat4 psFire(GsosBillboard input) : SV_Target{ float4 color = billboardTexture.Sample(linearSampler,

input.tex.xy); color.rgb = float3( color.a, pow(color.a, 4), pow(color.a, 10)); return color;}

#9.0

Page 48: GraphGame gg0 1 1-Particles

worldBillboardSize (1, 1)

Page 49: GraphGame gg0 1 1-Particles

Nagyobb tűzusing namespace Egg::Math;firstPersonCam = Egg::Cam::FirstPerson::create()

->setView( float3(0, 0, 200), float3(0, 0, -1)) ->setProj(1.2, 1, 1, 1000) ->setSpeed(50);

float4 worldBillboardSize(50.0, 50.0, 0, 0);

Page 50: GraphGame gg0 1 1-Particles

Particlevoid move(float dt){ position +=velocity * dt; age += dt; if(age > lifespan) reborn();}

Page 51: GraphGame gg0 1 1-Particles

Game::animatefor(int i = 0; i < particles.size(); i++)

particles.at(i).move(dt);

Page 52: GraphGame gg0 1 1-Particles

Game::animateID3D11Buffer* vertexBuffer = fireBillboardSet->getGeometry()-> getPrimaryBuffer();

ID3D11DeviceContext* context;device->GetImmediateContext(&context);D3D11_MAPPED_SUBRESOURCE mappedVertexData;context->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedVertexData);

memcpy(mappedVertexData.pData, &particles.at(0), sizeof(Particle) * particles.size());context->Unmap(vertexBuffer, 0);context->Release();

Page 53: GraphGame gg0 1 1-Particles

Hirtelen tűnnek el

Page 54: GraphGame gg0 1 1-Particles

Megoldás

• Korfüggő méret, intenzitás és átlátszóság

Page 55: GraphGame gg0 1 1-Particles

gsBillboardstruct GsosBillboard{ float4 pos : SV_Position; float2 tex : TEXCOORD; float opacity : OPACITY;};

float s = input[0].age / input[0].lifespan;...output.opacity = 1 - abs(s*2-1);

// és mindenhol szorozzuk s-sel a szélességet és magasságot

#9.0

Page 56: GraphGame gg0 1 1-Particles

psFirefloat4 psFire(GsosBillboard input) : SV_Target{ float4 color = billboardTexture.Sample(linearSampler,

input.tex.xy); color.rgb = float3(color.a, pow(color.a, 4), pow(color.a, 10)); color.a *= input.opacity; return color;}

#9.0

Page 57: GraphGame gg0 1 1-Particles

Simább tűz

Page 58: GraphGame gg0 1 1-Particles

fx/billboard.fxtechnique11 billboard { pass fire { SetVertexShader ( CompileShader( vs_5_0, vsBillboard() ) ); SetGeometryShader ( CompileShader( gs_5_0, gsBillboard() ) ); SetRasterizerState( defaultRasterizer ); SetPixelShader( CompileShader( ps_5_0, psFire() ) ); SetDepthStencilState( noDepthWriteCompositor, 0 ); SetBlendState( transparencyBlender, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF ); }}

#9.0

Page 59: GraphGame gg0 1 1-Particles

animate - rendezésusing namespace Egg::Math;struct CameraDepthComparator { float3 ahead; bool operator()(const Particle& a, const Particle& b) { return a.position.dot(ahead) > b.position.dot(ahead) + 0.01; }} comp = { firstPersonCam->getAhead() };std::sort(particles.begin(), particles.end(), comp);

Page 60: GraphGame gg0 1 1-Particles

Rendezéssel szép

Page 61: GraphGame gg0 1 1-Particles

400 részecske, kisebb alfa