Sign in to follow this  
CadeF

Rotation - Using a vertex shader for particle generators

Recommended Posts

CadeF    421
Hey everyone, I've got a few questions, all in HLSL. I'm trying and converting my particle system to use a vertex shader, the input vertices only contain texcoords (0 to 1) and their positions are between -1 and 1 (-1,-1 means the top left, 1,1 means the bottom right) so I can figure out which particle vertex I am modifying in the vertex shader. This is the structure of my application to vertex shader vertex format float4 position : POSITION0; float4 color : COLOR0; float2 tex : TEXCOORD0; float3 OrientF : TEXCOORD1; - Orientation towards camera, for billboarding float4 UTPos : TEXCOORD2; - Untransformed position of the particle in 3D world space Note, I will remove OrientF later, and replace it with CameraPos - UTPos when I put the camera's position in the shader. Currently, this is my vertex shader
void ParticleVS( in a2v IN, out v2p OUT ) 
{
    float3 F = IN.OrientF;
    float3 S = cross( float3(0,-1,0) , F);
    float3 U = cross( S, F);
    S = normalize(S);
    U = normalize(U);
    float3 Pos = IN.position.xyz;

    float4x4 matBillboard = float4x4( float4(S,0), float4(U,0), float4(F,0), float4(IN.UTPos.xyz,1));

    //Rotation (on the z axis) of the particle
    float cAngle = (IN.UTPos.w * 360) * (3.14 / 180);

    OUT.position = mul(mul(IN.position, matBillboard), matViewProj);
    OUT.color = IN.color;

    OUT.tex = IN.tex;
}




In HLSL, how would I implement the rotation of the particle on the z-axis? In VB.NET, I just use matAng = Matrix.RotationZ(Angle * (3.14 / 180)) and then set the world matrix to matAng * matBillboard. I have tried this,
float4x4 matRotateZ(float a)
{
float4x4 retMat = 1.0f;
float fCos = cos(a);
float fSin = sin(a);

retMat._11 = fCos;
retMat._12 = fSin;
retMat._21 = -fSin;
retMat._22 = fCos;

retMat._33 = retMat._44 = 1.0f;
return retMat;
}

    float cAngle = (IN.UTPos.w * 360) * (3.14 / 180);
    float4x4 matAng = matRotateZ(cAngle);

    OUT.position = mul(mul(IN.position, matAng * matBillboard), matViewProj);




But it seems to give me rotations in random directions. Rotating on the X or Y axis, works perfectly. Oddly enough, out of my matrix code, only the matRotateZ function seems to be wrong, the other two work nicely.
float4x4 matRotateX(float a)
{
float4x4 retMat = 1.0f;
float fCos = cos(a);
float fSin = sin(a);
retMat._22 = fCos;
retMat._23 = fSin;
retMat._32 = -fSin;
retMat._33 = fCos;
retMat._11 = retMat._44 = 1.0f;

return retMat;
}

float4x4 matRotateY(float a)
{
float4x4 retMat = 1.0f;
float fCos = cos(a);
float fSin = sin(a);

retMat._11 = fCos;
retMat._13 = -fSin;
retMat._31 = fSin;
retMat._33 = fCos;

retMat._22 = retMat._44 = 1.0f;

return retMat;
}

float4x4 matRotateZ(float a)
{
float4x4 retMat = 1.0f;
float fCos = cos(a);
float fSin = sin(a);

retMat._11 = fCos;
retMat._12 = fSin;
retMat._21 = -fSin;
retMat._22 = fCos;

retMat._33 = retMat._44 = 1.0f;
return retMat;
}



Thanks :) Edit: I can do z rotations using this code
    float3 F = IN.OrientF;
    float3 S = cross( float3(0,-1,0) , F);
    float3 U = cross( S, F);
    S = normalize(S);
    U = normalize(U);
    float3 Pos = IN.position.xyz;

    float4x4 matBillboard = float4x4( float4(S,0), float4(U,0), float4(F,0), float4(IN.UTPos.xyz,1));

    float cAngle = (IN.UTPos.w * 360) * (3.14 / 180);
    IN.position.x = Pos.x * cos(cAngle) - Pos.y * sin(cAngle);
    IN.position.y = Pos.y * cos(cAngle) + Pos.x * sin(cAngle);

    OUT.position = mul(mul(IN.position, matBillboard), matViewProj);
    OUT.color = IN.color;

    OUT.tex = IN.tex;

But I would still like to learn how to do this using a matrix created in a vertex shader. [Edited by - CadeF on April 25, 2006 6:41:20 AM]

Share this post


Link to post
Share on other sites
ET3D    810
One things seems wrong to me (after a superficial look at the code), and that's "float4x4 retMat = 1.0f;". Seems to me that you should be initialising to 0. Of course, this appears for the code of all your matrices, so I'm not sure it can accont for the difference, but it still seems wrong.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this