Sign in to follow this  

Billboard in vertex shader

This topic is 4089 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);
right.Normalize();
up.Normalize();

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

Wyzfen

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.
Thanks!

EDIT:
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

This topic is 4089 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.

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