Particle System Billboard & Rotation

Started by
21 comments, last by SiliconMunky 18 years, 7 months ago
Hello, I am implementing a particle system in my application. I am trying to get a billboarded particle system that can rotate as a whole. Right now I am 1) Drawing the textured quad (a "particle") at the origin. 2) Rotating it to face the camera. 3) Translating it out to its calculated position. The problem occurs when I try and rotate the system as a whole. Any rotation done after step 2) will throw off the billboarding effect and let me see the quads edge-on. However, the billboarding doesn't seem to work if the object is not drawn at the origin. (I am using the spherical billboarding code from Lighthouse3D (http://www.lighthouse3d.com/opengl/billboarding/index.php3?billSphe)). Does anyone have an idea what I can do so that I can maintain the orientation of the particles, but still rotate them as a system? Any help would be GREATLY appreciated! Thanks.
Advertisement
If I understand correctly, the problem is that after you rotate the particle system as a whole, the original orientation chosen to face the camera may no longer be valid. To counter this, I would first get the particles positioned exactly where you want them, and then compute the rotation matrix or matrices that will orient them toward the camera. There are several ways to do this, but an easy (viewplane-aligned) method is to construct the particle basis from the camera up vector, and the negatives of the camera forward and side vectors.

Let me know if that needs any clarification.

[Edit: noticed your username - are you a musician?]
Not quite sure I understand what you mean .. can you clarify?

Yeah I am a musician, been playing guitar for about 14 years now!
I think what jyk is saying, is that once you rotate the positions in your particle system, you then need to align each quad to the screen. You normally need to align the quads to the screen each frame because your camera is moving.

How are you storing the positions in your particle system?

I have a struct:

typedef struct{	CVector3 vParticles;	bool     bActive;	float    fLife;	float	 fFade;	float    fXVelocity;	float    fYVelocity;	float    fZVelocity;	float    fXPull;	float    fYPull;	float    fZPull;} ParticleStruct;


The position is contained in the vParticles member, which is just 6 floats (3 for position, 3 for color). I have a constant, MAX_PARTICLES, that defines how many ParticleStruct objects are created:

m_Particles = new ParticleStruct[MAX_PARTICLES];


So I'd need to align the quads again after I have already aligned them and moved them?
Quote:Original post by tritone
So I'd need to align the quads again after I have already aligned them and moved them?


You need to align them to your camera after their positions have changed. In my program what I do is this

step 1: update paticles positions, ie. loop through your list of positions and update where they should be - you can chose whatever algorithm you want to update the positions of the particles

step 2: take your first position and create a quad that is aligned to the camera and stick it in the vertex buffer (or whatever its called in openGl), or just render it. then do the same thing for every other position in your list. You need to re-align them every frame because your camera has probably moved and you'll need to make sure they are still facing the camera.


so each frame you'll want to update the positions (step 1) and then render all the positions (step 2).

Hope this helps. Are you able to align the quads to the screen when they aren't moving?


I can align the quads to the camera and move them just fine, however I am trying to rotate all the particles (as a system) after that:

Sample Code:

//Trying to determine the proper place for this glRotate call. //This is designed to rotate the entire system of particles 30 degrees//around the Y axis.glRotatef(30.0f, 0.0f, 1.0f, 0.0f);for(int iParticle = 0; iParticle < MAX_PARTICLES; iParticle++){ glPushMatrix();  TranslateQuadToPosition();  AlignQuadsToCamera();  glBegin(GL_TRIANGLE_STRIP);   glVertex3f( 1.0f,  1.0f, 0.0f);   glVertex3f(-1.0f,  1.0f, 0.0f);   glVertex3f( 1.0f, -1.0f, 0.0f);   glVertex3f(-1.0f, -1.0f, 0.0f);     glEnd(); glPopMatrix();  UpdateParticlePosition();}


Think of a rocket nozzle. I can make the particles stream out of the nozzle, however I am trying to rotate the nozzle at the same time and this causes the particles to become unaligned.
I think others have pretty much covered it, but your code sample there isn't going to work like you want it to. Your code has the effect of performing the following operations in the following order:

1. Align the quad to the camera (quad is centered at the origin)
2. Move quad to (unrotated) position
3. Rotate the entire particle system

As you've discovered, after number 3 the quad alignment is not necessarily valid. And, depending on what sort of alignment you're using, it might not be valid after number 2. What you need to do is:

1. Move quad to (unrotated) position
2. Rotate the particle system
3. Align the quad to the camera

This will probably require that you structure your code differently, put the pushes and pops in different places, and so on.

You might post your 'align to camera' function, as I'm guessing it'll need to be revised to work with an arbitrary position and orientation. Or, if you're happy with viewplane-aligned billboards (typical for particles), you can use the same orientation matrix for all the particles.

Sorry I wasn't more clear the first time. If this is still not entirely clear, I'll be glad to give a more concrete example.

What kind of music do you play?
It's already been said a few times, but you have to rotate the billboards to face the camera after all the rotation (and perhaps translation) has been done. If you orient the billboards toward the camera and then rotate the system, they obviously will no longer be facing the camera.

In my particle system, I rotate the particles to face the camera inside the vertex shader (each vertex contains its 2D offset and the location of the particle).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
jyk has got it right :)
I'm a little hazy on opengl's pushing and popping of matricies, so I can't guarantee what code advice I give is correct, but I'll give it a shot.

for(int iParticle = 0; iParticle < MAX_PARTICLES; iParticle++){  TranslateQuadToPosition();  glRotatef(30.0f, 0.0f, 1.0f, 0.0f);  glPushMatrix();  AlignQuadsToCamera();  glBegin(GL_TRIANGLE_STRIP);   glVertex3f( 1.0f,  1.0f, 0.0f);   glVertex3f(-1.0f,  1.0f, 0.0f);   glVertex3f( 1.0f, -1.0f, 0.0f);   glVertex3f(-1.0f, -1.0f, 0.0f);     glEnd();  UpdateParticlePosition();}


Ok, i'm sure this won't run properly, lol, but the point is as jyk said, you need to first translate the quad to its position, rotate it (the system), then align it to the screen and render.

Goodluck.

This topic is closed to new replies.

Advertisement