12
\$\begingroup\$

I am looking to the fastest way to create really simple particle effect that will be spammed like hell on the game...

Basically, my game looks like a vectrex game, made mostly of lines... I want to make some small explosions that will be really common.

There are something faster than just moving around some points and rendering with GL_Point?

\$\endgroup\$
3
  • \$\begingroup\$ +1 just for the Vectrex reference. I spent some fun hours on Scramble and Tempest as a kid in the early 80s. Without that I probably wouldn't have ended up as a game developer today. \$\endgroup\$
    – Kylotan
    Commented Jul 27, 2010 at 13:09
  • \$\begingroup\$ Yep, Tempest is awesome :D \$\endgroup\$
    – speeder
    Commented Jul 27, 2010 at 13:25
  • \$\begingroup\$ How I say that none is correct? \$\endgroup\$
    – speeder
    Commented Jul 28, 2010 at 12:26

7 Answers 7

13
\$\begingroup\$

There's really no need to store memory for every particle and animate each particle separately. You can do it procedurally by reconstructing the particle position during drawing by using the classic physics equation. s = ut + 1/2.a.t^2

A simple example (without constant acceleration of particles):


void drawExplosion(ExplosionParameters& s)
{
  Random rng;
  rng.seed(s.startSeed);
  glBegin(GL_POINTS);
  for (int i = 0; i < s.numParticles; i++)
  {
    vec3 vel = rng.getRandomVector(-1.0f, 1.0f) * s.explosionSpeed;
    float timeBias = rng.getRandom(0, s.particleTimeBias);
    vec3 pos = s.explosionCentre + (vel * (s.timeElapsed + timeBias));
    glPoint3fv(&pos);
  }
  glEnd();
}

Then you simply increase s.timeElapsed on every iteration of your update loop.

It is also completely amenable to being implemented on the GPU thus freeing up your CPU from having to do any work. A gpu implementation might look like this:

void drawExplosion(ExplosionParameters& s)
{
    //bind Vertex Shader If Not Already Bound();
    ...
    // bindVertexBuffer of Zeroes If Not AlreadyBound();
    glVertexPointer(...)
    //uploadShaderUniformsForExplosion(s);
    glUniform3f(...)
    ...
    glDrawArrays(GL_POINTS, 0, s.numParticles);
} 

The GPU vertex shader would then reconstruct the particle position via the physics equation and the uniforms/constants passed to it - just as the CPU version did.

To add some variance, you can use more simultaneous explosions with slightly differing parameters, animating colors/alpha, choosing differing starting positions. etc.

\$\endgroup\$
2
  • \$\begingroup\$ Also, you can use the predictability of pseudo random numbers to generate all the particles' initial vectors, creating hundreds of particles from a few int's worth of data. Using the GPU to create the quads is a really good idea for simple particles. \$\endgroup\$
    – Skizz
    Commented Jul 30, 2010 at 23:22
  • \$\begingroup\$ For years I've been making particle systems the traditional way with arrays of classes that treat particles as semi-intelligent entities and it always seemed kind of wasteful and bloated. This way is much better for basic particles that do nothing more than spew across the screen. \$\endgroup\$
    – Piku
    Commented May 13, 2014 at 22:06
7
\$\begingroup\$

I made several tests, and the FASTEST way (not the fastest to code) was particles made of GL_LINEs that knew their position and speed, and used that as the points when rendering (so, the faster the particle go, the most "line" it becomes, the slower, it becomes a point).

The effect is REALLY cool (look at any geometry wars video to see it), and REALLY fast too. Kick the crap out of quads (specially because quads would make me need to calculate the double amount of vertexes)

Also, it is better than using a already done particle system, because I wanted a specific and FAST effect, particle systems usually support lots of features, with proportional amount of overhead.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ +1 for explaining what you ended up doing, although I'd be curious to hear more details on your tests. =) \$\endgroup\$
    – leander
    Commented Aug 14, 2010 at 11:42
  • \$\begingroup\$ Btw: All of that was in immediate mode (that is the only thing that I know how to code, and I learned the name yesterday...) \$\endgroup\$
    – speeder
    Commented Sep 23, 2010 at 21:49
6
\$\begingroup\$

Normally I think you would do particles as texture-mapped quads. Treat them as 2D sprites basically, and fade them out over time, destroying them when invisible. Better still, reuse the old ones when you make new ones so you're not thrashing memory for these things.

If you use premultiplied alpha on the art then you can easily support lights, fire, smoke, and more besides all with one type of blending operation.

\$\endgroup\$
4
  • \$\begingroup\$ Hum... points are not FASTER than textures? \$\endgroup\$
    – speeder
    Commented Jul 27, 2010 at 13:25
  • 2
    \$\begingroup\$ Graphics hardware is specifically optimised for rasterising textures to the framebuffer. If points are faster, it's likely to be by a negligible amount, and you lose out on all the possibilities that you get with texturing. \$\endgroup\$
    – Kylotan
    Commented Jul 27, 2010 at 13:36
  • \$\begingroup\$ like... what? Mind you I am not making a full featured particle system, it is only a specific effect (small explosions, mostly for gameplay feedback that you hit something) \$\endgroup\$
    – speeder
    Commented Jul 27, 2010 at 16:46
  • \$\begingroup\$ If you just want to use points or lines, then that's fine. I can only comment on what most people do for particles. Maybe an unfilled triangle would make a nice particle. \$\endgroup\$
    – Kylotan
    Commented Jul 29, 2010 at 13:14
4
\$\begingroup\$

With OpenGL ES 2.0, ES 1.X with an extension and OpenGL => 2.1, you can use GL_POINT_SPRITES. GL_POINT_SPRITES are like a quad always in front of camera.

In fragment shaders, you can:

  • define sizes of sprite with gl_PointSize in vertex shader
  • use gl_PointCoord (uv coordinates) in fragment shader

You can use texture with alpha to draw ball sprites...

A tutorial for Point Sprites

\$\endgroup\$
1
  • \$\begingroup\$ I am avoiding extensions, the silly ones that the engine (that I don't made) already use, are alraedy sufficient to several people complain that the game don't run... \$\endgroup\$
    – speeder
    Commented Jul 27, 2010 at 22:18
1
\$\begingroup\$

Most particle effect systems I've seen, instead of drawing a huge number of points, draw a relatively smaller number of billboard textures where each textures looks a bit like an explosion. Unless your art style really prevents, you'll likely be happier going down that route. It will minimize the amount of particles you need to individually animate and render while still give a big visual effect.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ True, but he's aiming for the Vectrex style, it would work less well there. \$\endgroup\$
    – Kaj
    Commented Jul 27, 2010 at 21:20
  • 1
    \$\begingroup\$ Exactly what Kaj said... it would be pointless, AND would increase download size (I am switching the most graphics I can from sprite to true vectors, so I can reduce filesize) \$\endgroup\$
    – speeder
    Commented Jul 27, 2010 at 22:19
1
\$\begingroup\$

For a neat little way to handle the spawning/deletion/update of particles, assuming you have a simple array of particles - Particles[MAX_PARTICLES]:

Keep track of the active particles (starting with NumActiveParticles = 0)

New particles are always added at the end of the array:

pNewParticle = &Particles[NumActiveParticles++];

The clever bit - When removing a 'dead' particle - swap it with the last active particle, and decrement NumActiveParticles:

if ( DeadParticle < NumActiveParticles-1 )
{
  Particles[ DeadParticle ] = Particles[ NumActiveParticles-1 ];
}
NumActiveParticles--;

This avoids any searching for 'unused particles' when spawning, and avoids any scanning through an array of MAX_PARTICLES if none are in use.

Note that this only works if the update/render order is unimportant (as is the case for many particle effects, which use additive blending) - as this method of deleting a particle re-orders the array

\$\endgroup\$
-1
\$\begingroup\$

The fastest way i would assume is to find a particle engine and use that for your effects. Here are a few:

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .