Wednesday, 26 March 2008

Pixel Shader Particle Engine

I've finally got my pixel shader particle engine working. Its by no where near finished but its getting there. The position and velocity data for each particle are stored in 128bit (R32G32B32A32) floating point textures, though I may change the velocity one to 64bit as 128bit is overkill. To get some randomness to the particles, on initialisation I create a 128 x 128, or 256 x 256 etc. pixel texture and fill it with random floating point values between -0.5 and 0.5. Particle velocty is then calculated by adding a set velocity value to a velocity variance multiplied by the value stored in the random texture:

final velocity = initial velocity + (velocity variance * random value)

As I am storing particle velocity and position in a texture, the particle engine is not stateless, meaning that I can (and have) implemented varying acceleration. At the minute there is just a bit of gravity or any other linear force in there, but eventually I sould be able to achieve such effects as vortexes. I can also add some sort of collision detection if desired, entirely on the GPU.

Im using vertex texture fetching to get the position data in the effect that presents the particles to the screen. This involves creating a list of verts (one for each particle) then using these vert as texture coordinate to sample the position texture. I still eed to get different colours and sizes in there but thats just a matter of adding another 2 parameters to the a vertex decleration and filling it in.

Below is a picture of it in action, Im storing particle data in a 512 x 512 pixel texture, meaning there is a total of 262,144 particles on screen. Quite a few more than my CPU based engine!


2 comments:

Peter Bottomley said...

Cool! So basically all the data for each particle is stored in the colour values of a texture? Very handy. I suppose that also makes it extremely easy to save or load a particle system, storing all the data in a simgle image. Proper neato.

Unknown said...

Almost, the data stored in the textures arent static, there dynamic, so you cant save or load particle data in/from these textures (thats all done through code variables at the min), there used as a kind of buffer, so position and velocity is calculated in the pixel shader, then stored in these textures so that the final vertex shader can read the position data form them.