particle system

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • particle system

      Hi again, I'm back for more knowledge. I am building a particle system. I have just knocked one up quickly.

      It is structured thus:

      An entity can have a particle emitter component which contains a collection of particles (an arbitrary class at the moment) with certain data like other components, physics, transform etc.
      A particle emitter scene node is added to the scene graph and it passes commands to the renderer for all of the particles in the emitter components collection.

      I have implemented the physics separately from my current custom physics implementation because the particles aren't game entities current one has a lot of entity specific code at the moment (this made it clear it needs refactoring , decoupling). (Actually i just had a thought that i can subclass the physics component to handle particle emitters differently).
      And then there is a particle system that calls update for all particle emitter components and they handle spawning new particles.

      I considered having particles as entities themselves because then they could simply be composed of all my existing components for collision, physics, rendering and whatever else. But because the lifespan of particles will be variable but generally short and its possible for there to be thousands of them I think the entity collection is not a good option.

      I am after some design ideas and hints if there are any available. I remember when i built one years ago i had a particle buffer built on initialization and then used only that allocated space for particles. I tried that initially and then decided to just get it to work first. It's working now, but needs to be refined.

      I appreciate any hints, you guys always point me the right way.
    • You want particles to be as light-weight as possible, so it's a good call not to make them full-fledged entities. It sounds like you're on the right track.

      Is there something specific you want advice on?

      -Rez
    • One thing that I did not expect to have such a high performance gain with particles was a method I found in the book "Video Game Optimization" by Ben Garney. My first approach with particles was 'ok', however it broke down under high loads of particles, I took the initial approach of creating a particle class which essentially wrapped all of the information for a single particle, and boy was I surprised to see the leap in speed when I switched to this other method.

      The way you organize a list of data the way I initially wrote my particles is called an AOS or 'Array of Structures', each particle is a structure, and is held in an array.

      Source Code

      1. struct Particle
      2. {
      3. vec3 m_vecPosition;
      4. vec3 m_vecVelocity;
      5. ....etc
      6. };
      7. typedef std::vector<Particle> ParticleList;


      The suggested alternative was an SOA or 'Structure of Arrays' The difference here is that particles are defined in multiple arrays, ie.

      Source Code

      1. struct ParticleList
      2. {
      3. vec3 m_aPositions[NUM_PARTICLES];
      4. vec3 m_aVelocities[NUM_PARTICLES];
      5. };
      6. ParticleList m_ParticleList;


      I won't get into the details on WHY this is faster, it has many benefits to do with memory access, enabling SSE intrinsic's, and concurrency. Definitely check out the book though, it is what made our Orbito game go from slightly too slow, to faster than we would ever need it to be (the book is actually from a teacher at full sail).
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • Yup! Memory alignment and caching for the win!

      One small piece of advice regarding optimization which I also gave in the book. Don't bother with anything too crazy until you actually measure the performance and see where the bottleneck is. Whenever my game is running a bit slow, I'm almost always surprised where that time is actually going.

      -Rez
    • Also, I've never heard of the Video Game Optimization book, but flipping through it on Amazon looks promising. His chapter on common pitfalls includes the major things I warn people about (making assumptions and premature optimization being two big ones) and the basic breakdown of optimization techniques also looks pretty good.

      I think I'll order it and give it a whirl. :)

      -Rez
    • Yeah you won't regret it, the book is really well put together.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • 'Structure of Arrays'

      This is the kind of thing I was thinking about for purely optimization reasons.

      Is there something specific you want advice on?

      I was just thinking about how expensive newing up particles all the time could be. But, I just needed to hear, as I have read before, that pre-optimzation is bad. So I'll leave it as it is and revisit it should it become a bottleneck.

      The other thing I struggled with was trying to keep the particle classes data driven, but I have decided that each effect just needs its own particle definition and code for update and spawning particles and optimizations later.

      Cheers for the responses.
    • Another thing you could do is make a particle pool (if you go the way of an AOS to start, dead particles instead of being deleted would get passed back to the emitter class and marked as dead, than they would be re-used when a new particle is needed.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz