Jump to content
  • Advertisement
Sign in to follow this  
CadeF

Rotation - Using a vertex shader for particle generators

This topic is 4440 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
Advertisement
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
Initializing it to 0.0f cancels out matBillboard, and the z rotation still does not work.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!