Jump to content
  • Advertisement
Sign in to follow this  

Billboard in vertex shader

This topic is 4277 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

Hello, when I draw a billboard I usually do this:
Vector3 up    = camera.getUp();
Vector3 right = camera.getRight();

//pos is the billboard center in worldspace
points[0].m_pos = pos + (-right + up) * size;
points[1].m_pos = pos + ( right + up) * size;
points[2].m_pos = pos + (-right - up) * size;
points[3].m_pos = pos + ( right - up) * size;

This gives me a billboard in worldspace and works quite well in my oppinion. Now I tried to move some off the work to a vertex shader:
points[0].m_pos = pos;
points[0].m_off = Vector3(-size, size, 0.0f);

points[1].m_pos = pos;
points[1].m_off = Vector3(size, size, 0.0f);

points[2].m_pos = pos;
points[2].m_off = Vector3(-size, -size, 0.0f);

points[3].m_pos = pos;
points[3].m_off = Vector3(size, -size, 0.0f);
//vertex shader, g_transform = view * proj
output.pos = mul(float4(pos + off, 1.0f), g_transform);

As you probably can see, this billboard is only facing the camera if it is not rotated. Can I somehow make the billboard face the camera in the vertex shader? Do you think it will be faster/worth it? Thanks.

Share this post

Link to post
Share on other sites
In my particles system (using shaders), i store the quad's centre position and an 'index' for each vertex.
for the 2 triangles that make up the quad, i store indices (0,1,3) and (3,1,2) where the indices are clockwise around the quad

In the setup for the shader, i then set four vector4's representin each corner (the same as your original version) these are set up based on the view matrix, the same as your non-shader version.

Vector4[] quads = new Vector4[4];
DirectX.Matrix view = Camera.ViewMatrix;
DirectX.Vector3 right = new DirectX.Vector3(view.M11, view.M21, view.M31);
DirectX.Vector3 up = new DirectX.Vector3(view.M12, view.M22, view.M32);

quads[0] = new Vector4(up.X - right.X, up.Y - right.Y, up.Z - right.Z, 0f) * 0.5f;
quads[1] = new Vector4(right.X + up.X, right.Y + up.Y, right.Z + up.Z, 0f) * 0.5f;
quads[2] = -quads[0];
quads[3] = -quads[1];
SetVertexShaderConstant(EShaderConstants.Quads, quads);
SetVertexShaderConstant(EShaderConstants.Transform, Camera.ViewProjectionTranspose);

I then set those 4 vector4's as constants, and in the shader, use the quad index stored with each vertex to index the contants ...

mov r0, v0 ; v0 is the quad's CENTRE position
mov a0.x, v3.x ; v3 is my quad coord
add r0, c[QUADS + a0.x] ; QUADS is a constant to say which is the first vector4
m4x4 oPos, r0, c[TRANSFORM] ; TRANSFORM is my transpose view * proj transform

My particle system does a lot more than that in the shaders - scales, moves, textures and colours the quads, but the above is how it works out the facing etc. Not sure if using indexers is the best way, but it works.

hope that helps


Share this post

Link to post
Share on other sites
OK, I believe I understand what you are doing, I am going to try it.

Works well for me, and I assume it might be slightly faster than my old approach, although I have not tested that yet.

[Edited by - B_old on October 3, 2006 8:38:22 AM]

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!