How to make a billboard effect on particles?

How to do it? A single particle is made of four vertices. I have my camera matrix in matrix "view_matrix":

D3DXMatrixLookAtLH(&view_matrix, &cPLAYER_one->position,  &cPLAYER_one->lookat, &cPLAYER_one->up);

and the movement of the particles in matrix "move":

while(head != NULL)
      {
            for(int i=0; i<head->particle_amount; i++)
            {
                  D3DXMatrixTranslation(&move, head->particles[i].pos.x,  head->particles[i].pos.y, head->particles[i].pos.z);

                  cspine_device->SetTransform(D3DTS_WORLD, &move);

                  pmanager->render();
            }

            head = head->getlink();
      }

How should I change the parts in the matrices to make them face the camera? Try to explain it as clear as possible.
LVL 1
TuomasAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

chofreitherCommented:
Well, when I wrote a particle system in OpenGL, I did it like this:

I got the camera's up and right vector and used those to construct the quads on the fly. (You can extract the up and right vectors from the camera matrix easily.)

If you cannot or do not want to do this in Direct3D, I guess you could also take the camera matrix's rotation part (i.e. the upper left 3x3 matrix) and replace the translation with the particle's position. If you take this new matrix and transform a generic axis-aligned quad by it, it will face the same direction as the camera.

Hope that helps,
Clemens

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
TuomasAuthor Commented:
Allright! I got them face the camera! But is it normal that when the particles spread in all directions, the scaling looks funny (like the front quads go behind the back ones)? I made the matrix changes like this:

void c_spine::setup_default_camera()
{
      D3DXMATRIX view_matrix, rotmat2;

      cPLAYER_one->lookat.x = sinf(cPLAYER_one->angle)+cPLAYER_one->position.x;
      cPLAYER_one->lookat.y = cPLAYER_one->position.y;
      cPLAYER_one->lookat.z = cosf(cPLAYER_one->angle)+cPLAYER_one->position.z;

      D3DXMatrixLookAtLH(&view_matrix, &cPLAYER_one->position,
                                                       &cPLAYER_one->lookat,
                                                       &cPLAYER_one->up);
      
      
      D3DXMatrixIdentity(&bill);

      bill._11 = -view_matrix._11; bill._12 = view_matrix._12; bill._13 = view_matrix._13;
      bill._21 = -view_matrix._21; bill._22 = view_matrix._22; bill._23 = view_matrix._23;
      bill._31 = -view_matrix._31; bill._32 = view_matrix._32; bill._33 = view_matrix._33;

      D3DXMatrixIdentity(&scale);

      cspine_device->SetTransform(D3DTS_VIEW, &view_matrix);
}

And if I want the billboarding work on the x-axis movement of the camera, I should turn the 12, 22 and 32 into -view_matrix?

Oh, and here's the rest of the implementation:

D3DXMATRIX move;

      while(head != NULL)
      {
            for(int i=0; i<head->particle_amount; i++)
            {
                  D3DXMatrixTranslation(&move, head->particles[i].pos.x,
                                                             head->particles[i].pos.y,
                                                             head->particles[i].pos.z);
                  
                  bill._31 = move._31; bill._32 = move._32; bill._33 = move._33; bill._34 = move._34;
                  

                  D3DXMatrixMultiply(&move, &move, &bill);
                  
                  cspine_device->SetTransform(D3DTS_WORLD, &move);

Does this look correct or are there some errors?

Btw, how can I extract the up and right vectors out of the camera matrix?
chofreitherCommented:
When rendering billboards, you have to sort them yourself into back-to-front order and render them in that sequence, if I recall correctly. I think this is because you can't use z-buffering to render them because the entire billboard, even the transparent part, would fill the z-buffer and block anything behind it. It's been a while since I did those things, though....

As for extracting the vectors, you again use the 3x3 rotation part of the matrix, split it up into three rows and use the first as the x-vector, the second as y and the third as z.

Clemens

TuomasAuthor Commented:
Allright, I guess I'll be ok with these! Thanks alot!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.