Billboard shader with preserved pitch

I’m working on a simple billboard shader that always faces the camera but maintains pitch. If the camera rotates up around the x axis, the billboard will shrink as if looking down on an actual billboard. I can’t seem to get the latter to work.

Here is my vertex shader:

uniform mat4 mProjection;
uniform mat4 mView;
uniform mat4 mModel;

varying vec4 textureCoords;

void main(void)
	gl_TexCoord[0] = gl_MultiTexCoord0;

	mat4 temp = mView*mModel;
	temp[0][0] = 1;
	temp[0][1] = 0;
	temp[0][2] = 0;

	temp[1][0] = 0;
	temp[1][1] = 1;
	temp[1][2] = 0;

	temp[2][0] = 0;
	temp[2][1] = 0;
	temp[2][2] = 1;

	gl_Position = mProjection * temp * gl_Vertex;

	textureCoords = vec4(gl_Vertex.x + 0.5, gl_Vertex.y + 0.5, 0.0, 0.0);

I tried importing the pitch (in radians) as a uniform in an attempt to rotate the object back along the x but could not get it to work.

Anyone have any suggestions?

You need to compose the model matrix from the following vectors:
View direction (object position - view position, normalized)
Up vector (the billboard will only rotate along this axis)

From those two calculate the “right” vector (cross product between view and up vector)
And with the cross product between the up and right vectors you get the ‘true’ towards vector.
Then use the towards, right and up vectors (all normalized of course) to build the rotation matrix.

That’s assuming you still multiply the result with the view matrix.

Use glm::lookAt(). Or write your own version based upon the gluLookAt reference page if you aren’t already using GLM and don’t want to add it as a dependency for one function.

I’ll try both suggestions and see what I can come up with. Thanks guys!