Hey ya all.
I'm trying to model a blast wake using my gpu particle shader that takes points and creates quads.
I have it functioning, but I had to hard code timming values and opacity and the bit to expand the size.
I cant use my time delta its too small I set it to 1.5. Some Problem here
I tryed this for the alpha but its always 0.0
1.0f - smoothstep(0.0f, 1.0f, 1.0f/gGameTime); gGameTime is the whole time the game has been running big value
1.0f - smoothstep(0.0f, 1.0f, t1/1.0f);//t1 is the particles age and the age is updated with the time delta = 1.5 every time its rendered.
Don't Know How to fix it, Any Ideas.
oh and there is a problem when I rase the camera up high the wake goes into the terrain, it may be z fighting but I have it rased of the terrain by 100 units or it could be from with in my shader where I try to aline it to the world and not the screen.
here is the bit where I do the dody scaling and alpha reduction
Its done in the spawning new particle GS its the only place I can save the value in the vetex for this particel(Wake).
//we need to update our size here fSpeed is set to 1.5 (gParticleWidth and gParticleHeight) are set to 10.0
gIn[0].sizeW += float2(gParticleWidth, gParticleHeight) * fSpeed * gIn[0].age;
// Specify conditions to keep particle; this may vary from system to system.
//this is done on the alpha for this system
gIn[0].initialVelW.x -= ggrowamount;//grow amount is out value increaser set to 0.06
if( gIn[0].initialVelW.x > 0.0)//using the initialvelw.x for alpha and when it gets to 0 or less we stop
ptStream.Append(gIn[0]);
//this bit is to align it to the up direction May be wrong????????
//this will align it to the up +y direction OR OUR PASSED IN DIRECTION
float3 look = normalize(gEmitDirW);
float3 right = normalize(cross(float3(1,0,0), look));//maybe here 1 for x and 1 for z work 1 for y does not render
float3 up = cross(look, right);
float4x4 W;
W[0] = float4(right, 0.0f);
W[1] = float4(up, 0.0f);
W[2] = float4(look, 0.0f);
W[3] = float4(gIn[0].posW, 1.0f);
The Shader
heres the parts of the shaders needs looking at.
Spawns and updates particles
// The stream-out GS is just responsible for emitting
// new particles and destroying old particles. The logic
// programed here will generally vary from particle system
// to particle system, as the destroy/spawn rules will be
// different.
[maxvertexcount(2)]
void StreamOutGS(point Particle gIn[1],
inout PointStream<Particle> ptStream)
{
gIn[0].age += gTimeStep;//0.005;//
if( gIn[0].type == PT_EMITTER )
{
// time to emit a new particle?
if( gIn[0].age > 0.1)//gSpawnNewParticalTime )
{
float3 vRandom = RandUnitVec3(4.0f);
//vRandom *= gParticleSpreadAmount;
float3 offsettarget = gEmitDirW.xyz;// + vRandom;
Particle p;
p.initialPosW = gEmitPosW.xyz;// + vRandom;
p.pDirW = gEmitDirW.xyz;//normalize(offsettarget - p.initialPosW) ;//
p.sizeW = float2(0.5, 0.5);//very small to start
p.age = 0.1f;//vRandom.x;
p.type = PT_FLARE;
p.arrayid = 0;//vRandom.x % 2;//our array has 2 elements for testing
p.initialVelW.x = 1.0;//using this to fade our and stop the particle when it gets to 0 or less
p.initialVelW.y = 1.0;
p.initialVelW.z = 1.0;
//add new particle
ptStream.Append(p);
// reset the time to emit
gIn[0].age = 0.0f;
}
//dont keep the emitter all the time
//ptStream.Append(gIn[0]);
}
else
{
//we need to update our size here
gIn[0].sizeW += float2(gParticleWidth, gParticleHeight) * fSpeed * gIn[0].age;
// Specify conditions to keep particle; this may vary from system to system.
gIn[0].initialVelW.x -= ggrowamount;//grow amount is out value increaser
if( gIn[0].initialVelW.x > 0.0)//using the initialvelw.x for alpha and when it gets to 0 or less we stop
ptStream.Append(gIn[0]);
}
}//end
///////////////////////////////////////////////////////////////////////////////////////////////////
//draws the quad
// The draw GS just expands points into camera facing quads.
[maxvertexcount(4)]
void DrawGS(point VS_OUT gIn[1],
inout TriangleStream<GS_OUT> triStream)
{
// do not draw emitter particles.
if( gIn[0].type != PT_EMITTER )
{
//not using this her to compare so I dont forget later
// Compute world matrix so that billboard faces the camera.
//
//float3 look = normalize(gEyePosW.xyz - gIn[0].posW);
//float3 right = normalize(cross(float3(0,1,0), look));
//float3 up = cross(look, right);
//rotate the particle on the z
float r = gIn[0].angle;
float4x4 rotateZ = { cos(r), -sin(r), 0.0, 0.0,
sin(r), cos(r), 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
//this will align it to the up +y direction OR OUR PASSED IN DIRECTION
float3 look = normalize(gEmitDirW);// - gIn[0].posW);//gEmitPosW);//
float3 right = normalize(cross(float3(1,0,0), look));
float3 up = cross(look, right);
float4x4 W;
W[0] = float4(right, 0.0f);
W[1] = float4(up, 0.0f);
W[2] = float4(look, 0.0f);
W[3] = float4(gIn[0].posW, 1.0f);//rotatedpos, 1.0f);//
//rotate about the z so the image move around while still faceing its direction we set
W = mul(rotateZ ,W );
float4x4 WVP = mul(W, gViewProj);
//
// Compute 4 triangle strip vertices (quad) in local space.
// The quad faces down the +z axis in local space.
//
float halfWidth = (gIn[0].sizeW.x);
float halfHeight = (gIn[0].sizeW.y);
float4 v[4];
v[0] = float4(-halfWidth, -halfHeight, 0.0f, 1.0f);
v[1] = float4(+halfWidth, -halfHeight, 0.0f, 1.0f);
v[2] = float4(-halfWidth, +halfHeight, 0.0f, 1.0f);
v[3] = float4(+halfWidth, +halfHeight, 0.0f, 1.0f);
//
// Transform quad vertices to world space and output
// them as a triangle strip.
//
GS_OUT gOut;
[unroll]
for(int i = 0; i < 4; ++i)
{
gOut.posH = mul(v[i], WVP);
gOut.texC = gQuadTexC[i];
gOut.color = gIn[0].color;
gOut.arrayid = gIn[0].arrayid;
triStream.Append(gOut);
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////