3
\$\begingroup\$

What is a better idea for a particle generator (bearing in mind the intention to instance the draws to all the particles in the future)?

  1. A particle emitter that maintains its own list of particles and calls their update.
  2. A particle emitter that is passed through a global list of all particles in the world, adds the necessary particles to it and lets one global particle update take care of the rest.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Is this the same as your other question? gamedev.stackexchange.com/questions/20600/… \$\endgroup\$ Dec 6, 2011 at 4:14
  • \$\begingroup\$ nope. One is about how to best deal with the generated particles, the other is about the lifetime management of the emitter classes. \$\endgroup\$ Dec 6, 2011 at 10:12

4 Answers 4

5
\$\begingroup\$

The first option seems overwhelmingly preferable: it allows for the particles owned by a given emitted to be processed in bulk, and it allows you to do better broad-phase culling of objects. It provides locality of reference to your particles and implies far less per-frame maintenance of the same.

The second "global particle list" option is a bad design because it relies on a global unnecessarily and implies that culling non-visible clusters of particles involves inspecting every particle, or at least re-associating every particle with an emitter every frame, which will be inefficient.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Why would you need to associate the particles back with their emitters? Are the emitters just not the source of the particle, and instantly dis-associated after creation? \$\endgroup\$ Dec 5, 2011 at 19:26
  • \$\begingroup\$ It's not clear from the question how the lifetime of the particles differs for either option. The wording of the second option implied to me that particles and emitters are not associated permanently -- they don't need to be, but if they aren't you're probably culling individual particles instead of every particle for a given emitter. It's fairly open-ended, but almost none of the interpretations of the second option seem sane to me. \$\endgroup\$
    – user1430
    Dec 5, 2011 at 20:17
  • \$\begingroup\$ how would you deal with global forces that should affect all particles in a scene? like wind. \$\endgroup\$ Dec 6, 2011 at 10:37
  • \$\begingroup\$ Tell all emitters in the scene to apply the desired effect to their particles. \$\endgroup\$
    – user1430
    Dec 6, 2011 at 16:47
5
\$\begingroup\$

As with all other "preferable" or "best" approaches, it depends on what your end goal is.

For example, if you associate the particle list with it's emitter, this means that the emitter must continue to live until the particles have all decayed away. So your emitter needs to have more state. It needs to know whether it should be actively emitting more particles or in a "wait until all particles are gone" state. The latter doesn't make new ones. If you don't have this multi-state system, then the particles will all vanish the moment the particle system gets rid of them.

"Global" particle systems (it doesn't have to be "global" in the strictest sense. Just not bound to an emitter) allow you to de-couple emitters from the particles they emit. So your emitters can be very simple. Even better, you now have the ability to do different things you couldn't before. For example, you might want particles to respond to forces, like having particles near an explosion be pushed away by the impulse. Doing that with an emitter-based approach would be painful; you'd have to iterate through every particle emitter to make it work. With a "global" approach, you don't.

Then, there's the question of depth sorting. If multiple particle emitters start to interact, how do they sort with one another? Obviously this requires some level of 3D for it to matter. Again, the "global" approach makes this easier. Of course, you may not care about depth sorting between particle emitters, particularly considering sorting cost. But you have the option of caring with the "global" approach.

\$\endgroup\$
7
  • \$\begingroup\$ You talk about iterating over every particle emitter like that's a crime, but you'd still have to iterate over every particle at least in your case of response to explosions. That is, unless you create some spatial groupings, which is something an emitter could effectively do. As far as spatially related algorithms go (culling, collision detection, ...), I don't see how having an emitter is a detriment. \$\endgroup\$
    – notlesh
    Dec 6, 2011 at 0:37
  • 1
    \$\begingroup\$ @stephelton: Because each emitter is basically its own little isolated particle system. They cannot affect each other, and if you want global effects, then you need some central owner of all emitters. If instead all particles are equal, and all are governed by a central system, then you can play all kinds of games for spacial grouping. You can choose to group particles by emitter if that's what you want. But you don't have to. Having all particles under a central system gives you options. Flexibility is good. \$\endgroup\$ Dec 6, 2011 at 0:48
  • 2
    \$\begingroup\$ @stephelton: Having emitters isn't a problem. It's giving them too much responsibility that is the problem. The purpose of a particle emitter should be to create particles. That's all. It should not manage particles. It should not have a memory manager and such. It should create particles. It should decide when to create a particle, what direction it goes in, and maybe provide it pathing information. It should decide when to stop making particles and when it should go away. But it should not be responsible for managing them. \$\endgroup\$ Dec 6, 2011 at 0:53
  • \$\begingroup\$ This all sounds compelling. I'm just not convinced about the deficiencies you imply about an emitter-based system. \$\endgroup\$
    – notlesh
    Dec 6, 2011 at 1:32
  • 1
    \$\begingroup\$ @stephelton what don't you understand? An emitter is a thing that produces and discharges something (e.g a gas or radiation). Depending on your goal, thats all an emitter should do. It should simply create the particles, send them on their way with their own special properties, and be done with it. If particles behave in different ways (e.g water spray and magic fairy dust), their behavior should not be managed by the emitter. The emitter should simply know which particle-system to add the produced particle to; and let that manage the particles. An emitter is an emitter. \$\endgroup\$ Dec 6, 2011 at 2:23
4
\$\begingroup\$

I would go for the first option:

  1. It sounds simpler.

  2. It adheres to encapsulation principle better.

  3. It is likely that you will have to optimize the particle emitter. One of the common ways to improve speed is to have an array for particles and reuse the "dead" ones. I think it will be easier to handle if each emitter will be dealing with its own data.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ How does making each emitter deal with its own data make reusing dead particles easier? This would mean that each emitter would have its own array of potentially live particles. That's a lot of extra memory. Having a global chunk of memory for all particles makes it much easier to, for example, profile how many particles are in flight. That way, you can more effectively decide how big this buffer ultimately needs to be. \$\endgroup\$ Dec 5, 2011 at 23:16
  • \$\begingroup\$ @Nicol Bolas: You have a point there. \$\endgroup\$
    – Den
    Dec 6, 2011 at 10:06
  • \$\begingroup\$ @Nicol Bolas: there are some issues, correct me if I am wrong: 1) each emitter will have to iterate all the particles array to find a dead particle; 2) I will need to re-size the whole particle array when adding new emitters. \$\endgroup\$
    – Den
    Dec 6, 2011 at 16:02
1
\$\begingroup\$

After having read all of the excellent answers here, I'm actually now inclined to disagree with most. Nicol Bolas makes the point that every case is different and it might very well be useful to have all the particles in one place in order to exert global forces on them such as wind.

It has also been mentioned in other comments that this global approach may well be detrimental as you cannot refer to the particles as grouped by emitter, which can be very useful. However, I disagree with this. Nicol goes on to say in his comments that emitters should just emit - I agree with this.

So I have resolved to solve this problem by having emitters that do just that, emit particles that are added to a global list of all particles so that they can be affected by a number of global effects.

However, I propose a system where the particles have an additional index added to them, in the form of an integer, which represents their emitter so that they may be referred to in groups. Either that, or simply refer to them either globally in one big array of references, or through their emitters which maintain the smaller lists - depending on what you want to do.

\$\endgroup\$
3
  • \$\begingroup\$ I might be nitpicking, but you only list two options in your question and do not explicitly ask for any further suggestions for improvement or list any other (secondary) requirements. In my opinion all the answers submitted so far are fair candidates for marking as answer. \$\endgroup\$
    – Den
    Dec 6, 2011 at 16:09
  • \$\begingroup\$ "...refer to the particles as grouped by emitter, which can be very useful" Can you give an example when this can be useful? (This might be helpful for my own designs) \$\endgroup\$
    – Den
    Dec 6, 2011 at 16:13
  • \$\begingroup\$ I do realise that so I'm not picking this as the right answer, but I thought it might be of interest. As for when it's useful to be able to refer to them as grouped by emitter, well just for situations when you want to poll something against specific types of particle, such as fire or shrapnel... perhaps those aren't good examples, but I think it just gives the option of good locality of reference which could be good for deciding which groups to draw based on emitter rather than polling all particles - maybe a nice optimisation. \$\endgroup\$ Dec 16, 2011 at 12:37

You must log in to answer this question.

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