# Billboarding Matrices

## Recommended Posts

janoside    214
I am working on a particle system and I am having difficulty with the matrices for billboarding. Currently I have a list of vertices that are all parallel to the XY plane in their local coordinate system. I would like those vertices to be billboarded and maintain their position in space. Right now, my method is: -multiply the particle system's local world matrix by the camera's view matrix -set the upper-left 3x3 elements of the resulting matrix to the identity matrix -multiply the resulting matrix by the camera's projection matrix Then I apply the matrix resulting from these three steps to a vertex shader and I transform each vertex in the particle system by it. The result is a set of billboarded quads that do not maintain their position in 3d space; when the camera rotates around the particles, they do not rotate in space (I seem to be having trouble describing the issue, so here's an illustration:) From camera position 1 looking at 4 billboarded quads: ----------------------------------------------------- * (1) * (2) * (3) * (4) From camera position 2 looking at the same 4 quads from the other side: ---------------------------------------------------------------------- * (1) * (2) * (3) * (4) The desired result at position 2 is: ------------------------- * (2) * (1) * (4) * (3) I hope I am making sense. Any help is appreciated.

janoside    214
Any ideas?

##### Share on other sites
Quote:
 Original post by janosideRight now, my method is:-multiply the particle system's local world matrix by the camera's view matrix-set the upper-left 3x3 elements of the resulting matrix to the identity matrix-multiply the resulting matrix by the camera's projection matrix

I don't know what this would do, but I don't see how it would make a quad behave like a billboard.

There are 2 approaches (usually)...
(1) The first one is to "copy" the camera's orientation and apply it to the billboard quad. The camera's orientation is the inverse view matrix. Zero out the fourth row and column, hardcode the desired X,Y,Z position in the (1,4), (2,4) and (3,4) members, and simply render the quad with that matrix as the world transformation... You may have to negate the 3rd column of the matrix if the billboard aligns its backfaces instead of the front ones. This approach will not make the billboard "look at" the exact point where the camera lies, it will make it "look at" the camera's local XY plane.

(2) The other approach is to create a "look at" matrix from scratch. You start with the fact that you want the billboard's local Z axis to be the vector from the desired position to the camera position. Normalize it.
You then use a world reference vector (usually the world up vector) and find another local axis of the billboard as an appropriate cross product of its Z and the reference vector. How this is actually performed depends on the reference vector and the 3d system's handedness, but I don't think you'll have trouble figuring it out.
The third axis is simply calculated as an appropriate (with respect to its sign) cross product of the first two.
Given these vectors, the "look at" matrix which you should apply as the world transformation, is:
[ X.x   Y.x   Z.x   Pos.x ][ X.y   Y.y   Z.y   Pos.x ][ X.z   Y.z   Z.z   Pos.z ][  0     0     0       1  ]

All the above imply column-major vector transformation. If you want any clarifications on anything, just ask.

To be honest, I hesitated to answer at first, because I wasn't sure whether this is what you wanted...
I mean, this is what you wanted, if you wanted billboarding; but... you seem to have an issue with 4 *billboards* that don't align, not with the 4 *vertices* of a single one... (I hope I didn't misunderstand your post there...)

Did you manage to get four 3d points to always map to the same 2d points in the viewport? lol :)

##### Share on other sites
I was just going through your post once more and realized I had missed something important... I thought that the method you described in the beginning of your post was meant to be a world transformation for the particles!
However, you seem to want to override the transformation pipeline and project the vertices directly in screen space, yourself...

Quote:
 Right now, my method is:-multiply the particle system's local world matrix by the camera's view matrix-set the upper-left 3x3 elements of the resulting matrix to the identity matrix-multiply the resulting matrix by the camera's projection matrix

The weird thing is that the procedure you describe should be correct, so... why doesn't it work? The matrix you should multiply by the projection matrix (in step 3 you describe) should be a translation matrix in camera space that positions the billboard in the desired place in camera space. That matrix should be:
[ 1   0   0   BillPos dot CameraX ][ 0   1   0   BillPos dot CameraY ][ 0   0   1   BillPos dot CameraZ ][ 0   0   0            1          ]

The vectors "BillPos" (billboard's global position) and "CameraX/Y/Z" should be homogeneous vectors. In fact, they should be:
BillPos = (Pos.X, Pos.Y, Pos.Z, 1.0)
and CameraX/Y/Z should be the 1st/2nd/3rd row of the view matrix (all 4 members).
It's this matrix to which you must apply the projection matrix. (And don't forget to normalize the vertices with respect to their W!)

As I said though, it's quite weird, because I think that this is exactly the result you should be getting from your first two steps... Try and replace them with the aforementioned matrix directly.

The behaviour you mentioned (billboards not maintaining their position in gloabal space, but in screen space (!)) means that the billboards' global positions -somehow- cancel out from the entire product. This means there could be something wrong with their world matrices... (?)

If the above doesn't seem to work either, post the actual world/view/projection matrices, and details like system's handedness, vector transformation convention used etc...

##### Share on other sites
janoside    214
I really appreciate the help someusername. I think the problem that I am having is a result of an important detail that you and I both glossed over. When I describe my 3 steps, notice that I say:

"multiply the PARTICLE SYSTEM's local world matrix by the camera's view matrix"

I should have been more explicit about this fact. I am applying the same matrix to all of my particles. Is this a problem (clearly it is in the current state!)?

I have a set of vertices. In the set, each group of 4 vertices represents a single particle. I would ideally like to apply a single transformation to the entire set of particles. Is it possible to do so and arrive at a set of billboards in 3d space? I don't know how to do it, but it seems a necessary thing to be able to do since when rendering particle systems people often say that "batching" of the particles is a necessary method in order to achieve good performance. As I understand it the idea of batching requires that the same matrix be applied to multiple particles.

Thanks for any help.

[Edited by - janoside on March 27, 2006 10:22:01 PM]

##### Share on other sites
I see... That explains the behaviour you are getting. I had overlooked that detail.
I've never implemented a particle engine, I've only done billboarding, but I'm not quite sure whether you can get away with a single matrix for all un-transformed vertices...

I believe that the last matrix, before the projection, should have the members of its 4th column, equal to the dot product of billboard's center (in "particle system" space) and the respective camera axis (as homogenous vectors).
As you understand, this implies a different matrix for each billboard.

If you weren't using a "particle system" matrix you might be able to simply add the aforementioned dot products to the model space coordinates and transform only by the projection matrix.
But with the extra frame in between, it would be equivalent to creating a different matrix for each particle...