This page was last updated: May 17 ( = June -14 ), 2014
Particle systems are used in games, movies, etc. to depict phenomena such as clouds, dust, fireworks, fire, explosions, water flow, sand, insects, wildebeests, etc. Once you know what they are, you can't stop seeing them. To make a particle system work, you manipulate a collection of many 3D particles to exhibit some behavior. ( Look here for more information.)
In this project, you will use OpenCL and OpenGL together to make a cool particle system. (The degree of cool-ness is up to you.)
Your 3D environment needs to have at least two "bumpers" in it for the particles to bounce off of. Each bumper needs to be geometrically designed such that, given a particle's XYZ, you can quickly tell if that particle is inside or outside the bumper. To get the bounce right, each bumper must be able to know its outward-facing surface normal everywhere.
Let's face it. Spheres are computationally "nice". In computer graphics, we love spheres. It is fast and easy to tell if something is inside or outside a sphere. Determining a normal vector for a point on the surface of a sphere is even easier.
It is OK to assume that the two bumpers are separate from each other, that is, a particle cannot be colliding with both at the same time.
In the sample code, Joe Parallel wanted really badly to
make the code look cleaner by treating (x,y,z) positions and velocities
as single variables.
To do this, he typedef'ed new variable types called
point, vector, and color and took advantage
of OpenCL's float4 variable type.
(Unfortunately, there isn't a float3.)
He also stored a sphere definition as a float4: x, y, z, r.
typedef float4 point; // x, y, z, 1. typedef float4 vector; // vx, vy, vz, 0. typedef float4 color; // r, g, b, a typedef float4 sphere; // x, y, z, r constant sphere Sphere1 = (sphere)( -100., -800., 0., 600. );
Joe Parallel also stored the (x,y,z) acceleration of gravity in a float4 and hard-coded a time step:
constant float4 G = (float4) ( 0., -9.8, 0., 0. ); constant float DT = 0.1;
Now, given a particle's position point p and a particle's velocity vector v, here is how you advance it one time step:
kernel void Particle( global point *dPobj, global vector *dVel, global color *dCobj ) { int gid = get_global_id( 0 ); // particle number point p = dPobj[gid]; vector v = dVel[gid]; color c = dCobj[gid]; point pp = p + v*DT + .5*DT*DT*G; // p' vector vp = v + G*DT; // v' pp.w = 1.; vp.w = 0.;
Bouncing is handled by changing the velocity vector according to the outward-facing surface normal of the bumper at the point right before an impact:
if( IsInsideSphere( pp, Sphere1 ) ) { vp = BounceSphere( p, v, Sphere1 ); pp = p + vp*DT + .5*DT*DT*G; }
Assigning the new positions and velocities back into the global buffers happens like this:
dPobj[gid] = pp; dVel[gid] = vp;
Some utility functions you might find useful:
bool IsInsideSphere( point p, sphere s ) { float r = fast_length( p.xyz - s.xyz ); return ( r < s.w ); } vector Bounce( vector in, vector n ) { n.w = 0.; n = fast_normalize( n ); vector out = in - 2.*n*dot(in.xyz, n.xyz); out.w = 0.; return out; } vector BounceSphere( point p, vector in, sphere s ) { vector n; n.xyz = fast_normalize( p.xyz - s.xyz ); n.w = 0.; return Bounce( in, n ); }
To make this easier, an entire Visual Studio solution has been zipped up in the file ParticlesTemplate.zip
Please, please, please:
So, for Joe Parallel, the file name would be something like jparallel.cl The naming of the .cl file must happen during development because that file name is hard-coded into your .cpp program.
There is a constant character string near the top of the program called WINDOWTITLE where you set the string that goes in the graphics window title bar. Change Joe Parallel to your name.
Click here to see Joe Parallel's animation.
(It might work better to right click on the link and store the mp4 file locally
and run it from there.)
Feature | Points |
---|---|
Convincing particle motion | 10 |
Bouncing from at least two bumpers | 30 |
Dynamic color changes | 30 |
Performance table and graph | 20 |
Commentary in the PDF file | 30 |
Potential Total | 120 |