THIS HAS BEEN SOLVED. Feel free to let this thread die, but I welcome any feedback.
Hello all,
I am trying to do screen-aligned billboarding of some text labels, and I am having some trouble. The following is my code for calculating the billboard matrix:
// Up vector from view matrix
CEVector3 up = CEVector3Normalize(CEVector3Make(viewMatrix.m10, viewMatrix.m11, viewMatrix.m12));
// Normal vector from near plane
CEVector3 normal = [camera.viewFrustum planeAtIndex:NEAR].normal;
// Negate the normal vector
normal = CEVector3MultiplyScalar(normal, -1);
// Verify that up and normal are perpendicular. If not, something is wrong.
double dot = CEVector3DotProduct(up, normal);
if (dot < 0.00001) {
// Calculate the right vector
CEVector3 right = CEVector3Normalize(CEVector3CrossProduct(up, normal));
// Create billboard rotation matrix
billboardMatrix = CEMatrix4Make(right.x, up.x, normal.x, 0,
right.y, up.y, normal.y, 0,
right.z, up.z, normal.z, 0,
0, 0, 0, 1);
}
Then, to apply this matrix to a feature, I do the following.
// All features are at position 0 on the z axis. CEMatrix4 modelViewMatrix = CEMatrix4Translate(billboardMatrix, feature.position.x - cameraPosition.x, feature.position.y - cameraPosition.y, -cameraPosition.z);
I have tried also using the column vector of the view matrix instead of the row vector and transposing the billboard matrix, and all combinations, and nothing seems to produce the correct results.
My view matrix does have some weird transformations like scaling and shearing, not typical of examples of I've seen with billboarding. In fact, when I disable the scales and shears, the billboarding seems to work fine, but when I enable them again, it acts very very strange. The labels do show up, but they come in from all directions as I move the scene, and most certainly are not billboarded.
Can anyone spot my mistake? Any help would be most appreciated. Thank you.
EDIT - Update, I made the following changes: I transpose the billboard matrix after construction, and changed my translation code to:
billboardMatrix.m30 = feature.position.x; billboardMatrix.m31 = feature.position.y; billboardMatrix.m32 = 0; modelViewMatrix = CEMatrix4Multiply(inverseViewMatrix, billboardMatrix);
And this seems to produce billboarded text, as in the labels always face the camera, however, the labels are flush against the XY plane, rather than looking at the camera, so they are barely readable. Still not sure how to fix this problem.
EDIT2 - I think I got it, by not normalizing the camera up vector, it seems to have fixed the issue. It now appears to be properly billboarded. I think the problem is my scale was being lost. However, if anyone sees any errors in any of my math, please point it out, as I am certain that this is not perfect. Thanks.
Edited by metsfan, 20 March 2013 - 09:24 PM.







