As an undergrad I did a special graphics project integrating ray tracing and particle rendering. The particle system I wanted to render was the classic concert pyrotechnics. This particle system is different from a fountain, the main difference being that there is an air resistance factor that needs to be taken into consideration. The new particles are emitted from the source at a random velocity vector as shown from the initialization code.
private void initParticle(int i)
// loop through all the particles and create new instances of each one
mParticles[i].x = 0f;
mParticles[i].y = 0f;
mParticles[i].z = 0f;
float DOUBLESPEED = 20f;
mParticles[i].dx = (gen.nextFloat()*DOUBLESPEED) - (DOUBLESPEED/2f);
mParticles[i].dy = (gen.nextFloat()*DOUBLESPEED) - (DOUBLESPEED/2f);
mParticles[i].dz = (gen.nextFloat()*DOUBLESPEED) - (DOUBLESPEED/2f);
// completely random color
mParticles[i].red = (gen.nextFloat()*.5f)+.5f;
mParticles[i].green = (gen.nextFloat()*.5f)+.5f;
mParticles[i].blue = (gen.nextFloat()*.5f)+.5f;
// set time to live
mParticles[i].timeToLive = (gen.nextFloat()*1.5f) + 0f;
In this system the initial speed is exponentially decreased. In this case, decreased by nearly 100% of the max particle speed per second (taking into account the framerate of course). Below is the code added to the update method to apply air resistance
// apply air resistance
mParticles[i].dx = mParticles[i].dx - (mParticles[i].dx*AIR_RESISTANCE*timeFrame);
mParticles[i].dy = mParticles[i].dy - (mParticles[i].dy*AIR_RESISTANCE*timeFrame);
mParticles[i].dz = mParticles[i].dz - (mParticles[i].dz*AIR_RESISTANCE*timeFrame);
There are two demos in this release. The first just cycles a pyro. In this one, not only did each particle have a time to live, but it needed a second respawn timer. In the second demo, you touch the screen to set off a particle system. The code for that one is limited to 40 touches, so there is a set array of 40 systems. A better approach is to use a collection, so you can add pyro systems as they are needed. The key here is to remove them when all particles in the system have expired.
Another future improvement is to change the initial velocity direction to be a random point on a sphere. You can notice that the random direction and velocity vector is a point within a cube, so the particle system looks square. What should be done is a random direction is calculated from the surface of a sphere, and then that vector is scaled by a random velocity.
The triangles are starting to lose their looks. Not bad at a distance but close up they stand out. It might be time to start texture mapping the triangles to something more realistic. If we add the right GL blending, we could give the impression that a high concentration of particles would also mean a brighter color if their colors are additive.
The first touch for the pyro appears small. This is because the time between the init and the first frame is large, so the particle velocity gets reduced significantly. What should be done here is there should be more updates done at smaller time frames. So if a large frame rate appears, break it up into smaller time slices and simulate those (so multiple updates per frame).
Maybe for the next release I’ll try and get those features added. As always, the code can be found on Google Code. The demo is also available on the Android Market, search for “Particle System” or scan the QR code below