• Advertisement

Archived

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

Billboarding

This topic is 5937 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I''ve been using the following function for billboarding.
  
void teBillboard()
{
	float temp[16]={1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, m[16];
	glGetFloatv(GL_MODELVIEW_MATRIX, m);
	temp[0]=m[0];
	temp[1]=m[4];
	temp[2]=m[8];
	temp[4]=m[1];
	temp[5]=m[5];
	temp[6]=m[9];
	temp[8]=m[2];
	temp[9]=m[6];
	temp[10]=m[10];
	glMultMatrixf(temp);
}
  
It works fine asside from one problem. It makes the particles face the camera AND eliminates all effects of rotation. It should make them face the camera, but is there a way to do this with the particles being in the resulting rotated position?

Share this post


Link to post
Share on other sites
Advertisement
I think you are missing the whole point with billboarding here!
You use billboarding to make the particles always face the camera, and that will make it a little hard to rotate them!



- -- ---[XaOs]--- -- -

[ project fy ]

Share this post


Link to post
Share on other sites
You don''t see what I''m saying. When I rotate the camera, everything moves exept the particles. I WANT them to face the camera, but to have their center position moved. Understand what I''m saying? I just want to know if that is possible.

Alex Broadwin
A-Tronic Software & Design
-----
"if you fail in life, you were destined to fail. If you suceed in life, call me."
"The answer is out there."
"Please help, I''m using Windows!"

Share this post


Link to post
Share on other sites
When you multiply the current matrix by your "temp" matrix, you lose all translation informations.

Try this one instead :

  
float temp[16]={ 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f}

Share this post


Link to post
Share on other sites
I''m afraid that one just kills everything. When I use your temp it makes the particles all stretch from the center of the screen out to the lower left corner of the screen. I think you messed up somewhere.

Alex Broadwin
A-Tronic Software & Design
-----
"if you fail in life, you were destined to fail. If you suceed in life, call me."
"The answer is out there."
"Please help, I''m using Windows!"

Share this post


Link to post
Share on other sites
I have found this works fine for me:

float m[16];

glGetFloatv(GL_MODELVIEW_MATRIX, m);
glPushMatrix();
glLoadIdentity();
glTranslatef(m[12],m[13],m[14]);

... draw particle ...

glPopMatrix();


I suppose you could glLoadMatrix(m) at the end instead of the push/pop but I think the card probably does it faster than sending 16 floats...




Share this post


Link to post
Share on other sites
you do that for EVERY particle? Yikes! Overhead must be INSANE.

Alex Broadwin
A-Tronic Software & Design
-----
"if you fail in life, you were destined to fail. If you suceed in life, call me."
"The answer is out there."
"Please help, I''m using Windows!"

Share this post


Link to post
Share on other sites
OK what you need to do is NOT invert the 4th column of the matrix. I think how to do that is get the transformation matrix, then set everything to identity except the fourth column. This will reset all rotation and scaling to none (hopefully) giving you a quick billboard.

I read that somewhere on the Internet but I can''t find it now.

Share this post


Link to post
Share on other sites
Yeah, it kinda seems that way, eh? Is there a better technique? If you''ve got a bunch of seperate items that all need to point back at the camera, I can''t think any method will get around having to do a bunch of work each particle.

It''s not that bad, really. It''s all internal to the card ''cept for the get matrix call and the translate.

Share this post


Link to post
Share on other sites
My way you just call once, then draw all particles, then pop the matrix. Simple enough. But I think I''m inverting part I should not be.... I''ll figure it out soon enough.

Alex Broadwin
A-Tronic Software & Design
-----
"if you fail in life, you were destined to fail. If you suceed in life, call me."
"The answer is out there."
"Please help, I''m using Windows!"

Share this post


Link to post
Share on other sites
How does that work? Do you calculate your particle positions in camera space or something? I''d love to learn a faster technique.

Share this post


Link to post
Share on other sites
Oh wait. I see, you''re the one asking the question. Lemme know if you get it to work. What matrix are you grabbing in your glGetFloat call if not the matrix at each particle?

Share this post


Link to post
Share on other sites
Try the function I posted, just to see what I''m saying. Do this.

  
glPushMatrix();
teBillboard();
for(int p=0; p<particleCount; p++)
{
particle[p].Draw();
}
glPopMatrix();


And it will work. The position of the particle is done by the following

glVertex3f(particle[p].x, particle[p].y, particle[p].z);
.
.
.

Make sense? So my particle system and billboarding technically work, it just has one thing that is bothering me. Try it though.

Alex Broadwin
A-Tronic Software & Design
-----
"if you fail in life, you were destined to fail. If you suceed in life, call me."
"The answer is out there."
"Please help, I''m using Windows!"

Share this post


Link to post
Share on other sites
I take it your glTranslate calls happen in your draw routine...

I think I understand... This will only work with Translations and Scales, I think (which was your initial problem). I guess you only need to billboard at the point of the last rotation... I''ll see what speed improvements I get, as my particles for the most part are only translated.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
miles,

>I take it your glTranslate calls happen in your draw routine

I don''t know if I''m totally OT here, but you don''t call something like glTranslate *per particle*, do you ? If that''s the case: this is the most performance killing thing you can actually do. glTranslate or any other matrix manipulations have to be done per particle system. The particle positions themselves have to be passed by glVertex() or VA''s. See your psystem as a ''solid'' object, that is going to be translated, rotated, etc. Then, the individual particles are positioned with the appropriate coordinates through glVertex()

Imagine a 50k particle system, with a matrix call at every particle...
- AH

Share this post


Link to post
Share on other sites
I call glTranslate per particle, then draw a textured quad. Is there some means to accomplish this using some other method? I know I can certainly draw each particle as a gl primitive (like a point or something) using vertex calls, but I don't see how to do this with geometry at each particle...

or is it actually faster to have the processor create a few thousand quads based on the particle positions?


Edited by - miles vignol on November 23, 2001 7:46:36 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
> or is it actually faster to have the processor create a few thousand quads based on the particle positions

Ofcourse it is, thousand times faster. For my particle systems I do the following:

- there are always the same number of particles in the system, eg. if a particle is destroyed, a new one is instantaneously created.
- All particles have the same mesh topology (eg. quads)

I now initally create one or more vertex arrays with all vertex coordinates set to 0, but with a valid index array, that creates tri-strips of always 4 vertices (one particle). Texture coordinates are also generated that way.

Now for each frame I calculate the new particle positions (the particle physics), then a create camera facing quads using the CPU and repopulate the vertex-array, but NOT the index array, nor the texcoord array. This opeartion is rather fast, esp. if done in ASM.

I now transfer the VA to the 3d card (using nvidia''s AGP vertex_array_range transfers) and render it.
Note that the 3D card will *never* see the actual 3D particle positions that way, it will only see the 4 camera facing quad vertices. So no matrix modifications are necessary (or even possible) while the psystem is rendered.

IMO this is the fastest way to render a particle system, I can think of. Using this method you can easily render hundreds of thousands of particles with good framerates.

- AH

Share this post


Link to post
Share on other sites

  • Advertisement