The last post by Pieter was also about particles, but as I'm working with different software we have to redo some of the particle work. I'll go a bit deeper into the details of the implementation.
First of all a particle is a simple quad (but in general doesn't have to be) which always faces the camera. To make particles always face the camera we could calculate the transform needed for it to exactly face the camera. But doing this for all particles on screen is a bit expensive. Instead we simply take the rotation values of the camera and apply it to all particles. The effect of this is that not all particles are exactly facing the camera but they are roughly and the difference is not really noticable and it's a lot cheaper CPU-wise.
Second, the spawning and deleting of particles is expensive. Instead we're using a particle pool. In this particle pool there are only unused particles (not in the scene). Whenever we need to spawn a particle we take it from the particle pool, assign properties and add it to the scene. When the particle has to be removed, we're not going to delete it, but we return it to the particle pool. In this way we avoid the expensive operation of spawning and deleting particles.
Third, particles often fade out by using changing the alpha (transparency). Currently the only way we can change the alpha is by changing the material. In this case it would mean we cannot share the material across particles as changing the alpha of one particle would change the alpha of all particles. Using one material per particle would be possible but is very expensive as per material it requires shader program switches on the GPU. So we want one material for all particles but still change the alpha per particle, what now? Well, we can still change the UV coordinates of the particle (quad) and have different images with different alpha settings. We do this by using one large image which has several smaller images in it, see image below. For the first image we change the UV Coordinates to be between 0 and 0.125 (on the 'x' axis), for the second image between 0.125 and 0.25, etc. This functionality is also useful for animation.
Until next time!