Billboarding

Started by
3 comments, last by silvermace 19 years, 6 months ago
I need to set up a billboarding matrix but I don't have any LookAt- and EyePoint vector. My view matrix is set up like this:

D3DXQuaternionRotationYawPitchRoll( &qR, m_fYaw, m_fPitch, m_fRoll );
D3DXMatrixAffineTransformation( &m_matOrientation, 1.25f, NULL, &qR, &m_vecPosition );
D3DXMatrixInverse( &m_matView, NULL, &m_matOrientation );

Does anyone have an idea of how to calculate the angle between the camera and the object and set up the billboaring matrix correctly?
Advertisement
A billboard needs to face the camera. Typically you Y-Axis align them, so the object spins on the Y-Axis. If you don't need that, then you can look at the code and change it accordingly.

Basically you get the difference between the Objects location and Cameras location on the X/Z axis only. This will create a forward vector. Then you normalize it to bind it to the -1/1 range, and get the cross product to get the right vector. Then the up vector is hard coded since its Y-Axis aligned.

    D3DXVECTOR3 tempVec1, tempVec2;    D3DXVECTOR3 tempForward, tempUp, tempRight;    tempVec1.x = tempCamera(3,0);    tempVec1.y = 0;    tempVec1.z = tempCamera(3,2);    tempVec2.x = tempObject(3,0);    tempVec2.y = 0;    tempVec2.z = tempObject(3,2);    tempForward = tempVec2 - tempVec1;    D3DXVec3Normalize(&tempForward, &tempForward);    tempUp.x = 0;    tempUp.y = 1;    tempUp.z = 0;    D3DXVec3Cross(&tempRight, &tempUp, &tempForward);    tempObject(0,0) = tempRight.x;    tempObject(0,1) = tempRight.y;    tempObject(0,2) = tempRight.z;    tempObject(1,0) = tempUp.x;    tempObject(1,1) = tempUp.y;    tempObject(1,2) = tempUp.z;    tempObject(2,0) = tempForward.x;    tempObject(2,1) = tempForward.y;    tempObject(2,2) = tempForward.z;
find the angle between cameralookat and the positive Z-axis (0,0,1). That is the yaw amount for billboarding.
Do the same for pitch, thou for games that are on a flat plane (most games) I find yaw is enough.
________________
"I'm starting to think that maybe it's wrong to put someone who thinks they're a Vietnamese prostitute on a bull"       -- Stan from South Park
Lab74 Entertainment | Project Razor Online: the Future of Racing (flashsite preview)
If you keep track of your view matrix, you can also just take the transpose of that and multiply it by a translation matrix for the billboard object and set that to the world transform. Simple as 1, 2, 3. :)

Chris
Chris ByersMicrosoft DirectX MVP - 2005
err... can't you just reset the rotation part of your matricies?

over in the openGL forum it goes a little like this..
void CBillboard::Render(){	float mv[16];	// save the current modelview matrix	glPushMatrix();	// get the current modelview matrix	glTranslatef(position.x, position.y, position.z);	glGetFloatv(GL_MODELVIEW_MATRIX , mv);	// undo all rotations and scaling	for( int i=0; i<3; i+=2 ) {		for( int j=0; j<3; j++ ) {			if ( i==j )				mv[i*4+j] = 1.0;			else				mv[i*4+j] = 0.0;		}        }	// set the modelview with no rotations and scaling	glLoadMatrixf(mv);		RenderQuad();	// restores the modelview matrix	glPopMatrix();}
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website

This topic is closed to new replies.

Advertisement