# Rotation - Using a vertex shader for particle generators

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

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