Jump to content
  • Advertisement
Sign in to follow this  
mrmrcoleman

Particle system quicky...

This topic is 4889 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

Hello, I am just about to embark on creating my first particle engine and was wondering if you guys had any advice about what type of data structure should used to store the collection of particle objects in the particle system object. Although you guys probably already know I will give you a brief overview. There are a whole bunch of particles (probably 500 - 1000) in a collection of some sort. Each frame the list will be looped through and each particle will be updated, the particle could have died (lived it's on-screen lifetime) in which case the the particle will have to be reset somehow so that it starts again. Alternatively the particle may not have died so using the particle's data members (such as speed) combined with external factors (such as wind or gravity) other data members within the particle (such as current position) can be updated. So my question is which would be the best collection for this? A linked list of pointers? I have been using STL lists elsewhere in my program, would these be too slow? Thanks in advance for any help guys. Kind regards. Mark Coleman

Share this post


Link to post
Share on other sites
Advertisement
Since you're unlikely to want to reorder individual particles, just groups of particles, I'd probably suggest a list of buckets of some suitable size. Or maybe a list of particle systems, each of which has a list of buckets of particles. If you're an STL fan, I expect there's some STL equivalent to that with a nice short name :o)

Share this post


Link to post
Share on other sites
There're quite a few ways to order your particles. The last time I created a particle system I did it like this:

You have a pool of vertices. Probably an std::vector. You create a pool of the maximum number of particles particle pool[1000]. (you can look into boost::pool if you're a boost fan). Now you have allocated all the particles you need, just keep a boolean with each particle that says whether it is alive or dead. Process alive ones, ignore dead ones, and when you need to create a new particle, change one of the dead ones to an alive one.

Also, everytime a particle dies, make sure you add its index in the pool to some sort of stack. So next time you need to create a particle out of a dead one, you just assign it the index of the one you last killed. If there are no indices int he stack, then that means you're at maximum capacity.

Then after you process your particles, you go through pool array and just rener any particle that is in alive status.

Share this post


Link to post
Share on other sites
Quote:
Original post by mrmrcoleman
There are a whole bunch of particles (probably 500 - 1000) in a collection of some sort. Each frame the list will be looped through and each particle will be updated, the particle could have died (lived it's on-screen lifetime) in which case the the particle will have to be reset somehow so that it starts again. Alternatively the particle may not have died so using the particle's data members (such as speed) combined with external factors (such as wind or gravity) other data members within the particle (such as current position) can be updated.


Ok, I have a working particle system (no you can't see it) with large amounts of rendering small particles.

The following are tips, hints, and tricks I have found for rendering these massive amounts of small, moving partiles. Each hint will be preceeded by a description. If this description deosn't apply to you, then skip it.

/**********************************/
Collision Detection: If the particles are to interact in any way, either with each other or with mouse button clicks that alter existing particles or an object that will deflect the particles in anyway. Not if the mouse cursor is generating the particles.
/**********************************/

Use something called a Quad tree (if your program is 2D) or a Oct-tree if your program is 3d. Instead of looping through the entire list of particles to determine if they 'hit' something, you would only need to loop through small portions of the list of particles that are relatively close. I won't explain a quad-tree here, but a good explaination can be found on google or better yet, in a book at the local bookstore. Look for Lamothe edited series (large green books).

The cool thing is that the quad-tree (or oct-tree) can be added on after you have your particle system rendering. You don't have to edit your current data structures, nor do you have to edit your vector or list. You would keep the tree seperate from the data. You simply would have to write a function after the particle's postions are adjusted to insert the object's positions into the tree. You could use stl containers (vectors even) to store the leafs of the tree and clear() the container and reinserting them every frame.

Don't worry if this doesn't make sence, read about quad trees and STL and then come back.

/**********************************/
Smaller Rendering Lists: Looping through large particle lists delays the frame.
/**********************************/

This is pretty much a must, 2D or 3D. Instead of rendering 1000 particles that move, render 1/3 or 1/4 of them one frame, another 1/4 the next frame and so on and so forth.

Why does this speed up the frame? Imagine looping through 1000 particles every frame, updating their speed or position. This creates a large delay every frame just by updating the position.

Instead, update the particle position using the time since the last_frame_time. Basically, use a velocity and , multiply it by the frame slice last_frame_time to get the distance the particle should have moved. Then, to offset the delay of rendering the particles at different times, simply multiply the last_frame_time by 4 (or 3 if you divided into 3 units). This will 'jump' the particle to the corect postion, and efectively cut the framerate of the particle to 1/4 or 1/3 of the framerate of the rendering, but will still move at the same speed it did before.

You have to experiment with the number of chunks.

Also, Velocity = distance / time. Velocity * time = Distance.

/**********************************/
Compiled Sprite: For 2D particle systems only: If you are rendering large amounts of the same small set of images and the image is either completely on or completely off the screen (never half way) and the size of the render target is always known, then you can render straight to the screen without copying the image.
/**********************************/

Pros: speed
Cons: so many limitations and size considerations.

I do this so I can render 500+ particles. Fortunately, all of one kind of my particles are rendered completely on a surface. To avoid the surface size limitations, I render to an offscreen surface and blit that surface to the final surface. One large blit can be faster that 500 smaller blits, especially if you use hardware accelerated blits.

Full list of limitations:
Must know width of screen or offscreen surface you are rendering too.
Must not render on the edge of the screen (a work around is below).
Must have access to pixel buffer.
Have to compile sprite for 16 bit, 24 bit, and 32 bit screen depths.

Basically, you compile the small image into a C function. The cool thing is you don't have to render blank pixels, just the ones with color. because of different surface formats, you either have to restrict your demo to a single format by exclusive use of the screen, or you have to compile the bitmap 3 times to render to different desktop depths.

Instead of reading a pixel and copying it to a place on the rendertarget, checking for clipping and such, you can directly access the rendertarget buffer and change the color of the pixel without having to read it (also eliminating colorkey checks for pixels that will never be written anyway).

To work around the edge of screen limitation, simply make a rendertarget for the particles that is bigger than the screen. Then move the particle to the edge of the particle target which should be offscreen for the final rendertarget.

article: http://www.gamedev.net/reference/articles/article814.asp

Share this post


Link to post
Share on other sites
ok the eyes usually need only around 25-30 frames to see a smooth rendering


so if your app runs at 100 fps why would you update your particles every frame?


couldn t you create a list of e.g. 100 particles at a time sorted by texture

so you have 3 lists of 100 particels and update only one at a frame


also maybe you should create a texture with n frames of a animated particle so all you have to do is check the tex coordinates instead of rebindung a texture


render your scenery into the depth buffer first to make use of z occlusion since blending operations with the huge overdraw of particles are pretty expensive you see this in games like wolfenstein3d when you enter the particle flame of the flamethrower


another thing would be to do the billboarding with a pixelshader since there seem to be problems with the nvidia point sprite extension in opengl

well atleast me didn t manage it to get them sizing correct

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!