Particle system problem

Hello! I’m making a particle system, and it works quite well. The only problem is that I don’t know how to make the particles facing the screen. I need to do this by transforming the current modelview matrix somehow, because I also use mirrors, and I in this case I need to transform the mirrored modelview matrix. I don’t know if you understand what I want, but if anyone knows a tutorial or furmula to do this, I’d really appreciate that. Thanks in advance.

Are you drawing GL_POINTS or using quads? If quads (which I think you are) then what you need is a technique called billboarding.

-SirKnight

I don’t want to be annoying, but such questions are posted here every third day. Just do search… I don’t mean to insult you, but it’s somehow boring to read the same stuff every day . Well, OpenGL forum isn’t blooming lately…

Sorry, I didn’t know this is such a common problem. Now that I searched the forum, I found lots of threads dealing with this question…

I solved my problem, but there is something I don’t know why is happening. I have some stencil mirrors in the scene. I use a mirroring matrix to mirror the scene when rendering the mirrors. I also have to swap the facing of the polys. But not the particle polys! When I render them, I have to swap back the faces (but in only every even odd numbered mirror recursion when the faces are truly flipped). Why is this? I use the following matrix to transform the particle polys:
TForm[0] = 1.0f;
TForm[1] = TForm[2] = TForm[3] = 0.0f;
TForm[4] = 0.0f;
TForm[5] = 1.0f;
TForm[6] = TForm[7] = 0.0f;
TForm[8] = TForm[9] = 0.0f;
TForm[10] = 1.0f;
TForm[11] = 0.0f;
TForm[12] = (Center.x * MView[0]) + (Center.y * MView[4]) + (Center.z * MView[8]) + MView[12];
TForm[13] = (Center.x * MView[1]) + (Center.y * MView[5]) + (Center.z * MView[9]) + MView[13];
TForm[14] = (Center.x * MView[2]) + (Center.y * MView[6]) + (Center.z * MView[10]) + MView[14];
TForm[15] = 1.0f;
(I found this somewhere on the forum… TForm if the new transformation matrix, MView is the current modelview matrix)
Is this the problem? If so, how should I modify the matrix to avoid the extra face-flipping?

[This message has been edited by Catman (edited 10-26-2003).]

[This message has been edited by Catman (edited 10-27-2003).]

impressive. someone who knows how to do stencil mirrors but not how to rotate some vertices so that a quad faces the screen.

If the particles in your prog are not larger than 64 pixels on the scree AND you are using Nvidia hw from gf 4 ti up, you can use NV_POINT_SPRITE, which also increases performance a bit.

If the particles are larger, you simply have to find out two angles and rotate your vertices around them. quite simple…

Jan

Originally posted by JanHH:
impressive. someone who knows how to do stencil mirrors but not how to rotate some vertices so that a quad faces the screen.

Heh, maybe I sould learn matrix math.

Point sprites are not good for me because I antialias the old and new position of the particles (for rain) and this can’t be done with point sprites…

hm I’d guess that you can do everything with point sprites that you can do with quads (as long as the size is not too large)? because a point sprite is nothing else than a screen spacing quad… are you sure?

Jan

Imagine rain. Raindrops are falling from sky. They are fast so they look like thin lines. I render these thin lines using long quads.
I don’t know how point sprites work but I think this can’t be done with them. I think that the size of the point sprite can’t be changed separately in X/Y direction. Or am I wrong?

Originally posted by Catman:
Imagine rain. Raindrops are falling from sky. They are fast so they look like thin lines. I render these thin lines using long quads.

Kinda OT,

I’ve no idea how they create the rain effects in most games(first person that is). But I would think rendering raindrops as single colored/textured primitives must be very expensive. Isn’t easier/faster to just generate some rgba textures with painted rain and switch between them?

Originally posted by roffe:
[b] Kinda OT,

I’ve no idea how they create the rain effects in most games(first person that is). But I would think rendering raindrops as single colored/textured primitives must be very expensive. Isn’t easier/faster to just generate some rgba textures with painted rain and switch between them?[/b]

Roffe: that doesn’t work well for motion. Raindrops and snow give that “space warp” effect when you’re moving through them, plus a 3D bounce of surfaces is nice.

Catman: the main hint I’d give you on particle generation is that your math seems way over-done. There’s no need for a matrix per billboard unless the billboard has complex geometry.

The simplest way to construct quads that lies parallel to the image plane is to take the worldspace center point C and add or subtract two scaled basis vectors, Bx and By, where Bx is scaled camera-right and By is scaled camera-up.

There are four combinations of +/- Bx and By and those give you your four corner points. Scale Bx and By separately to give oblong sprites. Rotate Bx and By if you want. And mirror as needed, or just turn off cullface.

Avi

roffe: I also thougth that it is expensive, but it’s not. And with the processors getting faster particle systems get cheaper for realtime applications… At least I think so…

Cyranose: I don’t really understand your post. As I get it you say that I should use one matrix for all my particles. If so I don’t think that would work. If the particles are in a big area (like rain) at the edge of the screens the particles’ rotation would differ a lot.

Originally posted by Catman:
Cyranose: I don’t really understand your post. As I get it you say that I should use one matrix for all my particles. If so I don’t think that would work. If the particles are in a big area (like rain) at the edge of the screens the particles’ rotation would differ a lot.

Yes. That one matrix can be the identity matrix. The particles can be created in worldspace if the particle centers are relative to the world origin.

The error you’re imagining depends on FOV, but for a typical, say, 70 degree FOV, the difference is only a few degrees from doing the “every particle for itself” approach. However, the rotation error isn’t nearly as noticable as the skew near the corners, where a circular sprite is now somewhat elliptical. That’s the price.

However, it’s at least an order of magnitude faster since you can now draw all particles in one coordinate system one draw call (and one VBO) with very little setup math. I’ve seen particle-rendering speeds that almost reach the theoretical transform numbers for some cards. And that speedup has always won out in my projects.

When it comes down to it, there’s nothing “correct” about drawing 2D sprites or imposters for 3D effects. It’s all about speed and vast numbers of objects. If you want the most correctness possible, draw detailed geometry.

Avi

[This message has been edited by Cyranose (edited 10-28-2003).]

I understand it now… Maybe I’ll try it when it comes to optimization but I’ll have to convert my particles’ coordinates to worldspace then… But thanks anyway.

drawing long quads is not a particle system . I once implemented a very rough version of “rain” and simply used lines… it’s faster than quads, too.

But what I wanted is a general particle system that can visualize any kind of effects. If I were using lines, how would I imlement smoke?

I do not think that it is a good idea to fit the rain into your particle system (at least, I would not do so ). If you really really want to, your particle system could have an abstract something like myRenderingPrimitive which is, dependent on the usage, point_sprite or lines. You have coordinate chaos as well if you fit both into one, as a particle has a center position and a size, and a quad has four vertices (and a line has two). So if you really want to fit both into one class structure, you need an abstract primitive class which is, as I said, either point sprites or lines. If you use quads for rain and do not bother with class structure etc, you’ll have problems when simply rendering points, as you have to keep and manage (or at least calculate) four vertices instead of one, etc. So my final conclusion to this is a) it is not a good idea b) it is possible but only with an enhanced class structure.

sigh
Jan

I have to argue with you. All these effects fit perfectly into one particle system. I store only the center point of the particles, and at run-time I compute the four vertices of the quad. Moreover I store the old center position of the particles and then I use these two positions to compute the four vertices of the long quad (for rain). Here’s a graphic explanation:

x---------------x
| |
| |
| o |
| |
| |
| |
| |
| |
| |
| o |
| |
| |
x---------------x

o - old and new center position
x - vertices of the quad

I hope it is clear…

[This message has been edited by Catman (edited 10-29-2003).]

ok… sorry for not answering, I was too busy with bump mapping . your approach seems to be ok, so all you have to do is compute the vertices so the quad faces the screen. I guess you got this working in the meantime?

Jan

Yes, it’s working now (almost perfectly). The only problem is now with cylindrical billboarding. I use the following matrix to transform the particles:

TForm[0] = 1.0f;
TForm[1] = TForm[2] = TForm[3] = 0.0f;
TForm[4] = MView[4];
TForm[5] = MView[5];
TForm[6] = MView[6];
TForm[7] = 0.0f;
TForm[8] = TForm[9] = 0.0f;
TForm[10] = 1.0f;
TForm[11] = 0.0f;
TForm[12] = (Center.x * MView[0]) + (Center.y * MView[4]) + (Center.z * MView[8]) + MView[12];
TForm[13] = (Center.x * MView[1]) + (Center.y * MView[5]) + (Center.z * MView[9]) + MView[13];
TForm[14] = (Center.x * MView[2]) + (Center.y * MView[6]) + (Center.z * MView[10]) + MView[14];
TForm[15] = 1.0f;

The problem is that it rotates only around the y axis and when a particle’s direction is not paralell to the y axis it looks quite strange. The question is how should I modify this matrix to rotate around arbitrary axis?

[This message has been edited by Catman (edited 10-31-2003).]