Archived

This topic is now archived and is closed to further replies.

Hawkeye3

Billboarding

Recommended Posts

Hi, I''ve been perfecting a particle system lately and everything is going great except for one thing - when I rotate the world matrix the billboarding ''breaks''. The faces don''t look directly at the screen. In code, it looks like this(lots of stuff removed):
// Setup, this is the same for every particle

// so only do it once

D3DXMATRIX vMatrix;		// view matrix

pd3dDev->GetTransform(D3DTS_VIEW, &vMatrix);

D3DXVECTOR3 right, up, tRight, tUp;
D3DXVec3Normalize( &right, &(D3DXVECTOR3 (vMatrix._11,vMatrix._21,vMatrix._31)));
D3DXVec3Normalize( &up , &(D3DXVECTOR3(vMatrix._12,vMatrix._22,vMatrix._32)));

// ... within the particle loop ..

tRight = right;
tUp = up;

tRight*=pParticles[i].size[0];
tUp*=pParticles[i].size[0];

D3DXMATRIX rMatrix;
D3DXVECTOR3 axis;

D3DXVec3Cross( &axis, &up, &right );
D3DXMatrixRotationAxis( &rMatrix, &axis, pParticles[i].angle );
D3DXVec3MultMatrix( &tUp, &tUp, &rMatrix );
D3DXVec3MultMatrix( &tRight, &tRight, &rMatrix);

pVerts[i*4+0].Init( pParticles[i].pos-tRight+tUp, color, 0.0f, 0.0f);
pVerts[i*4+1].Init( pParticles[i].pos+tRight+tUp, color, 0.0f, 1.0f);
pVerts[i*4+2].Init( pParticles[i].pos-tRight-tUp, color, 1.0f, 0.0f);
pVerts[i*4+3].Init( pParticles[i].pos+tRight-tUp, color, 1.0f, 1.0f);
Currently I am getting the view matrix, then extracting / normalizing the up and right vectors from it. Then I scale those by the particle size and then I find the cross product and rotate each particle by that (to get rotation effects). Then I finally create the faces to be used by the particle system with some math. Originally I planned on rotating the matrix used to rotate the particles by the inverse of the world matrix, but this didn''t work so I removed it. My math really isn''t all that good so I don''t know what else I should try. Oh, and does anyone have a link that explains Axial aligned billboards?

Share this post


Link to post
Share on other sites
Are you updating the billboard-effect every frame?

Since the View-matrix moves, you will have to recalculate the billboards to face the camera


or am i missunderstanding?

[edited by - ZitherMan on July 27, 2003 1:16:41 PM]

Share this post


Link to post
Share on other sites
Matibee : thats where I got the code I''m using now from. Like I said though, if I rotate the world matrix it comes out wrong.

The code you see here is inside of the emitter''s Draw() function, so it is being called every frame(and the particle loop is called once per particle). Also, the effect isn''t *totally* broken. The faces just seem distorted depending on how much I rotate the world matrix.

Basically the effect I''m trying to create is so that I can ''attatch'' the emitter to an object, so that when the object rotates, the emitter will rotate too.

Share this post


Link to post
Share on other sites
quote:
Matibee : thats where I got the code I''m using now from.

Funny, I don''t see any matrix/vector multiplies in Dunlops code.

Anyway, some suggestions..

1) Don''t rely on GetTransform(). AFAIK some hardware does not support it, make your view transform acessible to this code.

2) Drop the support for rotated particles until it works without rotation. If you want your particles rotated on the screen about the centre, you''re going about it the wrong way. Come back and ask again when it''s up and running (sorry I can''t explain now I''m pressed for time, discrete surfing in the office..)

3) Zitherman has a point. Your particles should be emmited in World Space. Then before rendering set an identity matrix as your world transform.

quote:
Oh, and does anyone have a link that explains Axial aligned billboards?

They''re simple really. For example, to make a 2d billboarded sprite look like he''s always "standing up", replace your up vector with (0, 1, 0) - a normalised up vector.

Share this post


Link to post
Share on other sites
I appreciate the continued replies.

The matrix/vector multiplication is for allowing particles to be rotated on THEIR axis as opposed to the world axis, you know, so you can actually have them rotate. Thats why I get the cross product of the up/right vectors so I get a normal for the axis to rotate around. If I comment this code out, the particles still get distorted if I rotate the world matrix.(they just don''t rotate around themselves anymore).

I should of said that I got the BASE to my code from that site.

1) If GetTransform isn''t reliable, why is the site using it?

2)"Drop the support for rotation"? Exactly which rotation? The per-particle rotation or the world rotation? Per-particle rotation works fine... and as long as I don''t rotate the world the particles appear perfectly. Oh, and I feel honored that somoene would take time out of their work to answer my questions.

3) I don''t really understand this one... what are they being emitted in now? And if I load an identity matrix the emitter will only show up at the origin...

If you want/aren''t busy, I''ll e-Mail you the exact emitter header and a running executeable so you can see the problem in real-time.

Share this post


Link to post
Share on other sites
quote:
I appreciate the continued replies.

The matrix/vector multiplication is for allowing particles to be rotated on THEIR axis as opposed to the world axis, you know, so you can actually have them rotate. Thats why I get the cross product of the up/right vectors so I get a normal for the axis to rotate around. If I comment this code out, the particles still get distorted if I rotate the world matrix.(they just don''t rotate around themselves anymore).



Well you sure can''t do it the way you are trying.

quote:

1) If GetTransform isn''t reliable, why is the site using it?


Ideal world I guess. Perhaps it is fully supported from dx9, but this was a problem I came across in dx8 so decided never to rely on GetTransform again (i don''t need it in my simple scenes and scene management).

quote:

2)"Drop the support for rotation"? Exactly which rotation? The per-particle rotation or the world rotation? Per-particle rotation works fine... and as long as I don''t rotate the world the particles appear perfectly. Oh, and I feel honored that somoene would take time out of their work to answer my questions.


I think you are getting the particle transformations right around your neck, Dunlops example is six lines of almost perfect code (barring the GetTransform thing). It will work perfectly no matter how you rotate the view if you implement it correctly, then you may move onto to other things.

quote:

3) I don''t really understand this one... what are they being emitted in now?

Well if anyone should know you should

quote:

And if I load an identity matrix the emitter will only show up at the origin...

Mmmm. Then I assume you are emitting particles relative to the emitter, then setting the emitters transformation matrix to draw them??? You''re way off the mark if you are. If you''re emitter has an X,Y,Z world coord, and you emit a particle from it at X1,Y1,Z1 then the particle world coord is X+X1,Y+Y1,Z+Z1.

You MUST use an identity matrix to render the particles- no ifs no buts. If you can''t see why, then just trust me, if you can''t trust me then.........

quote:

If you want/aren''t busy, I''ll e-Mail you the exact emitter header and a running executeable so you can see the problem in real-time.

If you''re going to send me code, at least send me the whole thing (VC workspace included, but get rid of all the intermediate files!) so I can change it, test it and recompile it.

Share this post


Link to post
Share on other sites
Ah ok, I''ve figured out a way to use the identity matrix, and instead of rotating the world matrix, I''ll rotate the vector that is used for the emitter direction instead. Sorry for all the trouble.

Share this post


Link to post
Share on other sites