fast particles, how ?

Started by
3 comments, last by DMINATOR 18 years, 3 months ago
Hi Well I had made some particle engines before, but using immediate mode, which was the simplest. I am thinking of using Vertex Arrays for this now, to support some of the oldest hardware. Has anyone made particle engine with Vertex Arrays and was it worth ? Or maybe some other way, still some old cards friendly. Any links or info would be most welcomed, and thank you for your replies.
Advertisement
Hello..

VertexArrays, or even better: VBO:s is "always" better than imidiate mode.
(and to be sure, profile both ;])
point sprites help as well.
How old hardware are you talking about..?

Only recent article I read was on how to use render to texture and save everything as textures... doesn't go well with your old hardware criteria though.

Good luck!
If you have something that can use vertex arrays, it can also be used with VBOs (using mapping). You can easily abstract the particle update, the particle geometry generation, and the geometry storage into separate objects, to allow mix/match for the current card.

A fast particle engine typically has pre-allocated storage for all the state about a specific article, times the maximum number of particles in use for that system (say, 500). Then, it runs a loop over all the particles, where it updates the state of the particle record, using the same code for all the particles (to avoid too much branching). You can, potentially, keep a "first alive/last alive" pointer to update only a sub-range of the array, but doing something like following a linked list or pointer in an array would be death (because of the cache misses). If some particle in the middle of the list dies before the particle after it, don't attempt to handle this specially -- just make a "dead" particle render with alpha = 0.

Once all the data is updated, you run through the array again with a second function, which knows how to generate geometry from the data. The arguments to this function are the source array, number of particles, and world-space up-right and down-right vectors (to use for generating the quads). To rotate particles, you probably want to rotate the UV coordinates instead of the generated geometry, which will save a few multiplies and adds.

Now, as for what you do in updating the particle state, that's up to how fancy you want to be. If you're really fancy, you generate a bit of assembler code that only updates the actual parameters used by the effect in question (because you probably want to support things like animating colors, animating size, evolving speed based on gravity and air drag, etc, but not necessarily all at the same time in all effects).

Even without code generation, this is still a very efficient way of treating particles.
enum Bool { True, False, FileNotFound };
I know this may be slightly OT (with regards to Vertex Arrays vs. Imm.Mode), but I just wanted to offer another approach to updating particles.

The technique is as follows: when updating particles, you have an 'input' pointer to the particles used last frame and an 'output' pointer to the particles to use the next frame.

very simple eg.
void UpdateParticles(SParticle *psInPtr, int iNumInputParticles, int &iNumOutputParticles){    SParticle *psOutPtr;  psOutPtr = psInPtr;  iNumOutputParticles = 0;  while (iNumInputParticles)  {    // if this particle is still alive,    if (psInPtr->fTime < psInPtr->fLife)    {      // update time, integrate, apply forces, rotation, colour calculation etc...      psOutPtr->fTime = psInPtr->fTime + fTimeElapsed;      psOutPtr->sPos += (psOutPtr->sVel * fTimeElapsed);      // the omission of the following step when the particle is dead actually      // guarantees that the dead particle will be overwritten by subsequent      // particles.      iNumOutputParticles++;      psOutPtr++;    }    psInPtr++;    iNumInputParticles--;  }}


In effect, you can get rid of a massive amount of 'dead' particles by not incrementing the output pointer if the 'input' particle is dead - effectively allowing subsequent particles to overwrite dead particles.

This scheme would be used in conjunction with a separate emission scheme. Once you've updated your buffer, you can then 'emit' new particles at the very end of the buffer once you have no gaps in it.

Another technique: If you're a bit tight on memory you can generate thousands of particles deterministically with virtually no memory, provided you have a suitable pseudo random number sequence generator. My little game SETH (http://www.justinpaver.zskilz.com/files/projects/sethdemo03.zip) used this method for all of it's particles.

do unto others... and then run like hell.
Thank you for your replyes, il take a look at these suggestions.

I am aiming at cards starting from ATI 3D RAGE PRO, which are still used by some people I know.

This topic is closed to new replies.

Advertisement