PDA

View Full Version : Particle system problem



Catman
10-21-2003, 06:32 AM
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.

SirKnight
10-21-2003, 07:06 AM
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

Zengar
10-21-2003, 01:47 PM
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 http://www.opengl.org/discussion_boards/ubb/smile.gif. Well, OpenGL forum isn't blooming lately...

Catman
10-26-2003, 12:39 PM
Sorry, I didn't know this is such a common problem. http://www.opengl.org/discussion_boards/ubb/smile.gif Now that I searched the forum, I found lots of threads dealing with this question...

Catman
10-26-2003, 02:33 PM
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).]

JanHH
10-27-2003, 08:47 PM
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

Catman
10-28-2003, 12:39 AM
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. http://www.opengl.org/discussion_boards/ubb/wink.gif

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...

JanHH
10-28-2003, 01:25 AM
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

Catman
10-28-2003, 02:39 AM
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?

roffe
10-28-2003, 09:18 AM
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?

Cyranose
10-28-2003, 10:06 AM
Originally posted by roffe:
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?

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

Catman
10-28-2003, 11:20 AM
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.

Cyranose
10-28-2003, 07:46 PM
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. http://www.opengl.org/discussion_boards/ubb/smile.gif

Avi


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

Catman
10-29-2003, 12:28 AM
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.

JanHH
10-29-2003, 02:36 AM
drawing long quads is not a particle system http://www.opengl.org/discussion_boards/ubb/wink.gif. I once implemented a very rough version of "rain" and simply used lines.. it's faster than quads, too.

Catman
10-29-2003, 02:50 AM
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?

JanHH
10-29-2003, 03:13 AM
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 http://www.opengl.org/discussion_boards/ubb/wink.gif). 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 http://www.opengl.org/discussion_boards/ubb/wink.gif
Jan

Catman
10-29-2003, 05:53 AM
I have to argue with you. http://www.opengl.org/discussion_boards/ubb/smile.gif 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).]

JanHH
10-30-2003, 08:56 PM
ok.. sorry for not answering, I was too busy with bump mapping http://www.opengl.org/discussion_boards/ubb/wink.gif. 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

Catman
10-31-2003, 02:38 AM
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).]

vmh5
10-31-2003, 06:28 AM
quote:
--------------------------------------------------------------------------------
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.

--------------------------------------------------------------------------------

Actually it's not FOV it's the difference between 1 point and 3 point perspective. If you're using one point perspective (only fore shortening along z). All sprites orthogonal to z will be perfectly billboarded irregardless of their xy position. If you're using 3 point perspective (which no one does) every sprite has to point at the camera center.

Cyranose
11-01-2003, 02:43 PM
Originally posted by vmh5:
Actually it's not FOV it's the difference between 1 point and 3 point perspective. If you're using one point perspective (only fore shortening along z). All sprites orthogonal to z will be perfectly billboarded irregardless of their xy position. If you're using 3 point perspective (which no one does) every sprite has to point at the camera center.

Um, no, I don't think so.

Perhaps you can explain how one can code one-point vs. three-point perspective in an opengl perspective matrix. I always thought n-point perspective was an artistic technique useful for manual drawing with a ruler.

In reality (or in CG in this case), an unrotated cube drawn in the center of the screen using a simple, say, 70 degree perspective frustum will exhibit qualities of a drawing made using one-point perspective, that is the edges parallel to the z-axis will appear to meet at one point in the distance. That same cube, now rotated 45 degrees around its up axis will appear as if drawn with two-point perspective. And if it's shifted towards the bottom (or top) of the window, it will now appear as if drawn with three-point perspective, that is the "parallel" six edges of the three visible faces will appear to meet at three points in the distance, perhaps off-screen, but the effect is more pronounced the greater the FOV.

The circular distortion I mentioned does indeed happen with your basic perspective frustum and its visual effect does increase with FOV. Try it yourself and you'll see. However, I consider this a small price to pay for the big speed improvement.

Avi

vmh5
11-14-2003, 05:59 AM
I may be abusing the term 3-point perspective. What I mean is that the object is fore-shortened not just based on its distance along the camera z axis (which is the typical 3d technique) but foreshortened by it's real xyz distance to the camera (which is how reality works). If you use xyz distance for perspective and move a rectangular plane with the same normal as the camera off center along the y axis it will no longer look like a rectangle since one vertical edge will be further away (in xyz sapce) than the other. With the z-distance only approach it will remain a rectangle, this is actually really bizarre but doesn't seem to bother anyone. I thought somehow you were trying to compensate for this... but I missed that you were using 3d sprites and you're just trying to compensate for the fact that you can see more of the side of the 3d sphere when it's off-center...