Jump to content
  • Advertisement
Sign in to follow this  
reapz

Projectiles and Particle Systems

This topic is 2396 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently working on optimising the allocation of particle systems in a game I'm working on. I'm curious to see what other people think.

Lets say we have Projectiles, in this case a Rocket projectile. The rocket projectile has a smoke trail which persists even after the rocket impact. Should the rocket have ownership of this particle effect? I say it should create a ParticleEntity which gets added to the world separately and store a pointer to it.

My current solution has been to have a ProjectileFactory which manages the reusable projectile objects, each one has a particle type ID which refers to a particle pool inside the ParticleSystemManager class. The ParticleSystemManager holds pools of reusable ParticleEntity objects essentially. All of these classes exist on the game side of the code, not the engine. I guess I'm just curious how other people handle this sort of thing.

I have also been meaning to take a look in Q3 or HL2 source code to see how they do it but haven't got around to it yet.

Share this post


Link to post
Share on other sites
Advertisement
I think this, like most other programming questions, usually have to be answered with "it depends". Although I will say this: if you're looking to optimize this, I would suggest that you go the way of DX10+ and take full advantage of the geometry shader. Having your graphics hardware deal with the particles as closely as possible is the ideal, I would say - so your particle manager ought to sit as closely to shaders as is (reasonably) possible.

As for whether, say, a rocket should own the effect is entirely up to you, although I think that spawning an individual particle manager per projectile would be ill-advised. This is an architectural choice but I think you should just go with whatever seems cleanest and makes the most sense to you. Personally, I would rather have the particle manager spawn emitters at every relevant projectile and update them collectively.

I think also just consider how much optimization you really need - there's no need to go overboard, and work out a clean design first - "premature optimization is the root of all evil".

Share this post


Link to post
Share on other sites

Lets say we have Projectiles, in this case a Rocket projectile. The rocket projectile has a smoke trail which persists even after the rocket impact. Should the rocket have ownership of this particle effect? I say it should create a ParticleEntity which gets added to the world separately and store a pointer to it.

No. Ask the scene manager which also owns the rocket to make a new particle effect given some parameters. If the rocket owns the particle the particle will move with the rocket and die with it.
The rocket may have been the trigger that spawned the particle effect but there is otherwise no other logical connection between them. The rocket doesn't even need a pointer to the effect. Just spawn it and go.


L. Spiro

Share this post


Link to post
Share on other sites
What I didn't say is that this project is for mobile devices so as of right now I have no geometry shader.

In my case a particle system is a collection of emitters and affectors so I can't just spawn an emitter at every projectile location. Each one is a self contained effect. My main issue is that I can't just give every Projectile its own particle system because sometimes the life of a particle exceeds the life of a projectile and vice versa.


I think also just consider how much optimization you really need - there's no need to go overboard, and work out a clean design first - "premature optimization is the root of all evil".


I don't feel like pooling objects which are reused over the course of the game to be premature optimisation. I consider this intelligent optimisation. Using the new and delete keywords at runtime is generally bad for performance in games, and I am not delving into low level memory management with custom allocators.


If the rocket owns the particle the particle will move with the rocket and die with it.


What if the smoke particle is a lingering effect, and I can't just kill it once the rocket dies. I understand what you're saying about linking them through the scene structure rather than ownership, I'll have to mull on that.

Share this post


Link to post
Share on other sites
An owner and a parent are not the same thing. I am wondering if you originally meant that the rocket should parent the smoke.
Everything should really be owned by the scene manager.
If you then want smoke to be attached to the rocket and move with the rocket (and possibly die with it) then you could parent the smoke by the rocket.
As a parent, the rocket's transform should be propagated to its children.

When the rocket does you have the choice of unparenting the smoke and leaving it to die on its own at its last-known world coordinates, or kill it with its parent.

But generally smoke does not follow the rocket. It stays where it is spawned and dies on its own.


L. Spiro

Share this post


Link to post
Share on other sites
Well, you could attach a particle emitter to the rocket that constantly calls the particle system's addXXX method. When the emitter dies the particles will still get updated.
I would break down the particle code into different classes:

ParticleEmitter: SphereEmitter (emits inside a sphere), MeshEmitter (emits particles from the vertices of a mesh), RingEmitter, ... etc.
ParticleAnimator: animates particle properties over time like size, rotation, color, UVs, position, adds gravity, etc.
ParticleRenderer: BillboardParticleRenderer (aligns quads with camera), TrailParticleRenderer (creates a trail from the oldest to the newest particle), etc...

That way you can combine those to create a big number of different particle effects.

I havent played around with DX10 stuff like geometry shaders yet, basically because of my stone-age-hardware :D So I can't say what you would do different there.

Share this post


Link to post
Share on other sites

An owner and a parent are not the same thing. I am wondering if you originally meant that the rocket should parent the smoke.


With the game I'm working on the game logic and rendering logic are separate, so on one side I have game Entity objects and the other I have Scene objects in the classic scene hierarchy with cascading transforms. When I say owner, I mean the RocketEntity owns a ParticleEntity. The RocketEntity looks after a SceneNode object which holds a Mesh object and the ParticleEntity looks after a SceneNode with the ParticleSystem object. I have these two separated because the ParticleEntity is freed after the Rocket is freed.

There are two particle cases I've had to consider and in both cases I have wanted the ParticleEntity to be readded to a reusable pool when it has completed. The first case is that the particle has an infinite duration and will only stop emitting when told to, this does not mean the particles should just disappear but the emitters should stop creating new particles. The second case is a particle of finite length, in both cases once they are finished they get reset and added back to a reusable pool of ParticleEntity objects. This behaviour needs to occur regardless of other game entities.


ParticleEmitter: SphereEmitter (emits inside a sphere), MeshEmitter (emits particles from the vertices of a mesh), RingEmitter, ... etc.
ParticleAnimator: animates particle properties over time like size, rotation, color, UVs, position, adds gravity, etc.
ParticleRenderer: BillboardParticleRenderer (aligns quads with camera), TrailParticleRenderer (creates a trail from the oldest to the newest particle), etc...


My current setup is something like this:

A ParticleSystem can have a number of ParticleEffectGroups. A ParticleEffectGroup has a ParticleRenderer (Billboard, Beam, Ribbon etc) as well as ParticleEmitters (Box, Point etc) and ParticleAffectors (Colour fade, velocity etc). This has allowed me to get some complex particles into the game and hasn't provided more than was needed. My main concern has been where to store all the instances I need over the course of the game so I am not calling new/delete constantly, my solution was to create a PoolManager essentially.

Think about this case:

If the player holds down the shoot button they can only ever have 2 rockets active in the game world at any one time. You might logically only pre-cache 2 smoke trail effects, one for each rocket but what if the smoke trail lingers after the rocket trail impact, and you go to fire another rocket but we have no cached particle effect yet because the smoke trails are still fading out and have not been freed yet.

My main problem is still how to handle the lifetime of the ParticleEntity objects so that are not directly coupled to GameEntity objects. Right now I have wrapped a ParticleSystem into a ParticleEntity object which monitors the lifetime of the ParticleSystem and puts it back in the pool when done.

Share this post


Link to post
Share on other sites
A related question: how to manage "live objects"? Such as smoke particles in this case.
In the past, I used reference counting with some success, but I'm now transitioning to a garbage-collected environment. To let an object exist I need to reference it and to let it be cleaned I need to have no references. But unless I have a proper call to figure out if an object can be forgotten, this cannot work.
I'm actually keeping a list in a parent object which is updated using a proper call, for a specific game object but I have some doubts in generalizing that.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!