So in this past week my group managed to get particles working in the game, the system used is one that I had made last term and it was updated by the lead programmer (Kenny) to work with the rest of the game. In light of this, I'm going to take the chance to talk about the development of the system, any future plans for it as well as what interesting effects we should be able to attempt later on in the term as well as particles in general.
Introduction
So to give a bit of an overview of what our system contains: We have a Particle class, which is used for each individual particle in the system and contains the force being applied to the particle, the position, colours, etc. The particles I use are simple billboards, that is to say they consist of two triangles with a sprite applied to them; A Particle System class, which contains is used to update the list of particles as well as all the information relative to spawning new particles (e.g. the spawn deviation (the area around the center of the system in which a particle can spawn), the spread deviation (the range for the particles impulse velocity), etc.); A Particle Manager, which is a singleton that holds a list of Particle Systems which can are all updated and drawn through this manager. The specifics of each of these will be explained in more detail as I go through the development.
The Particle and Particle System
So I'm going to sort of speed through the first few hours of the development. I started off with a single Particle, it wasn't tied to any system (the System class not having been made yet) and lacked some of the functionality it has today. The particle could have an impulse force applied giving it acceleration which would make it move and such.
Once I had the particle moving and rendering properly, I started work on the System aspect. This started it's life as something that would just spawn a bunch of particles and let them loose...It was pretty boring. That's when I began to go a little crazy with it and began to add all these little extra things as they popped into my head. I think it's easier if I just list them at this point so here's all the extra features I went ahead and added as time went on (in order):
Spawn Deviation - This allowed me to specify an area around the center of the system which a particle would be randomly spawned in. So if I specify a minimum spread of [-5,-5,-5] and a max of [5,5,5] then the particle will spawn anywhere within a 10x10x10 cube, treating the System's position as the origin.
Spread Deviation - This would add an impulse velocity of a random value to a particle, based on the same min-max idea as the Spawn Deviation. This is particularly useful as it can let me make particles spread out from a source or fly in random directions along a plain or make it look like a steady wind is affecting the particles.
Decay Values - I decided to spruce up the particles themselves by adding an initial/decay colour and initial/decay transparency. The initial values are the values of the particle when it spawns and the decay values are the values of the particle when it dies. I then interpolate between these values LERP and the particle's current life (normalized) to figure out what the current colour should be.
Life Range - So the standard particle has a life time to it, which basically says how much long the particle will be around for before it dies. To make the system appear a bit more dynamic I made it so that you could specify a range which will change how long the particle is alive for. For example, if you add a Life Range of 0.5 and the life of the particle is 2, then particles will have a life time that will be randomly determined to be within 1.5 and 2.5
Scale Deviation - This lets you add a randomization to the scale of each particle so that some will appear smaller and some will appear larger. This is also to help with the more dynamic appearance of the system.
Volume Types - This let me specify the different volume types for the systems. This really only impacts the spawn positions of the particles so that they're limited to be within a cylinder or a sphere, rather than a regular and boring cube. When coupled with the next feature it can also lead to other things such as rings.
Min-Max Radii - This let's you specify a minimum radius and a maximum radius within which the particle should spawn. This discards any particles which are spawned outside of the specified range.
Explosion Types - To make things a bit more interesting I added the ability to set the system to an explosion type. These will make the particles fly away from the center of the system or towards the center of the system to simulate an explosion or an implosion respectively.
Okay. That's it for the development of my System (the manager was introduced later but it doesn't add any interesting visuals to it, and then Kenny updated it to render in newer versions of OpenGL using the GPU). To take a break from the wall of text I'm going to just show you a couple of examples of what the results of the system are. I'll include the sprite beside the system it's used with.
So these are the kinds of particles we have now. Really simple, just slight modifications to the colours of the actual sprite and letting them blend with each other. Some of the results can be quite impressive but it is pretty limited in terms of the types of visuals you can pull off, even with shaders...
OR SO I THOUGHT!
Particles with Frame Buffer Objects
So FBOs (Frame Buffer Objects)are just fantastic with shaders. They let you take things up to another level by allowing you to influence the raw final data of the system during each update rather than being able to only affect each individual particle. For example, let's break down this ink particle effect from the game
Brutal Legends which can be found here:
http://vimeo.com/10082765
So as you can tell right off the bat, each particle is just a semi-transparent black spot which is moving around (though that's going into Fluid Dynamics which is a tale for another day). We let the particles move around according to their dynamics and when we go to render we begin thresholding in the fragment shader. If a value that will be outputted is below a certain value then it will be discarded, eliminating the more translucent aspects from the render process while they can still be used to calculate the positions of the other particles. After the values have been discarded we do another pass of the image and add a blur to it which gives the particles their lighter outline. The result is a flowing ink effect.
Naturally there's plenty more we can do now that we can actually apply effects to the final results of a particle system rather than each individual particle, which should help make things plenty interesting. Though that doesn't mean we should make each system render using a FBO, in some instances like the first particle system I showed we may just want to use it as is, in which case a VBO would be better as it would not be as stressing on the hardware though this goes more into optimization than anything else.
Looking back I may have jumped the gun on this blog a bit. It's starting to drag out a bit so I think I'll call this part 1 of a series of posts on particles. Next time (which may or may not be next week, we'll find out) I'll go into other interesting things we can do with particles as well as how we can use the GPU to help improve the current system.
Until next time, cheers!