Page 1 of 1

Deleting a particleEmitter? & Cool method to reduce batches

Posted: Sat Mar 10, 2012 8:36 am
by areay
Hi guys,

I'm working on a game where there may be heaps of particle effects going on - possibly hundreds of ParticleSystems, using the same template script, on the screen at any one time. Although the systems are often using the same template script each one represents an extra CPU->GPU batch which I don't want.

What I've done to get around this is to have a single static (C++ static that is) ParticleSystem in the relevant class and then have instances of the class create ParticleEmitter http://www.ogre3d.org/docs/api/html/cla ... itter.html instances which the class instances manage themselves . For example, a particular projectile in my game has a unique explosion effect - the C++ class that defines this projectile has a ParticleSystem that is initialised once when the first object of this type is instantiated. Each object of the class creates a ParticleEmitter via the static ParticleSystem.

Here's the static initialisation code (done once)

Code: Select all

m_pHitParticlesSystem = m_pSceneMgr->createParticleSystem("RocketProjectileClassExplosions", "particleTemplateName"); //setup the ParticleSystem in the normal way
m_pHitParticleSystem->getEmitter(0)->setEnabled(false); //disable any emitters that the template defines
m_HitParticleOriginalQuota = m_pHitParticles->getParticleQuota(); //we store the count of particles that the system would use for a single object - we'll be adding this to the quota for every new object
m_pSceneMgr->getRootSceneNode()->attachObject(m_pHitParticleSystem); //attach it the world origin as the position of emitters are an offset from the owning ParticleSystem
Here's what each new object does

Code: Select all

m_pHitParticleEmitter = m_pHitParticleSystem->addEmitter("Point"); //create a new emitter 
m_pHitParticleSystem->getEmitter(0)->copyParametersTo(m_pHitParticleEmitter); //copy the default emitter's config to the newly created emitter
m_pHitParticlesystem->setParticleQuota(m_pHitParticleSystem->getParticleQuota() + m_HitParticleOriginalQuota); // each new object means our ParticleSystem must be able to handle more particles overall
This is all well and good, I can have huge numbers of the same effect going on and all in one batch, yay.

However, there is a problem (not a big one though), there's no great method for removing the particle emitters when the owning object gets deconstructed. The ParticleSystem class allows me to create an emitter but its removeEmitter function takes only an integer index to the emitter, this is fine if you're defining each emitter 'explicitly' and you know exactly where each emitter is in the ParticleSystem's 'list' of emitters but if stuff is happening randomly at runtime then you can get gaps in the list and indexes cease to be relevant (assumption!). There's no way to get the index of an emitter and no function like removeEmitter(Emitter *) which is what I'm needing.

I don't understand how Ogre's ParticleSystems work under the hood, I haven't even looked at the source, but I'm hoping someone can come to the rescue here - perhaps it'd be an easy addition to make to the API? As I say it's not causing me any problems whatsoever but it is gnawing away at my mind as it's a (small in my case) memory leak and possibly a performance problem over a long enough time scale. I am using pooling where appropriate which mitigates some problems but that's not
the point dagnamit.

Anyway, I hope this might help someone else who is wanting more particle awesomeness but is worried about batch count.

Cheers
Al

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Sun Mar 11, 2012 4:07 am
by xfxsworld
i think i am understand what you said and maybe there are two problems.

1. in ogre one particle emitter is one batch. so I think you are not decrease the batch count.

2. maybe you will have sort problem...

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Sun Mar 11, 2012 8:58 am
by areay
I did test that extra emitters do not create extra batches, that part is working fine.

I tried keeping track of each emitter's index via wrapping it all up in a struct with its emitter integer index and then recycling them via freelists but its damn ugly

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Sun Mar 11, 2012 2:16 pm
by xfxsworld
sorry i made a mistake. i review the source code of ogre and you are right, extra emitters won't create extra batches. even this, i do not think put all same template script to one particle system is a good idea. especially in complex environments, sort will be a big problem, just In my opinion...

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Sun Mar 11, 2012 11:27 pm
by areay
Hey xfxsworld, can you tell me what you mean by 'sort problem' ??

Are you talking about the ParticleSystem sorting its emitters by distance from the camera or something?

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Mon Mar 12, 2012 8:03 am
by xfxsworld
when you use additive blend( src = one, dest = one ) material i think it will be fine with the method what you talked about. because we do not need to care about the render order( back to front, or front to back ), the result is same.

but if you use normal transparent blend( src = alpha, dest = 1-alpha ), we must render from back to front. so in this case, i think the final result of render all same template script particle system in one batch maybe will not you want...

try to make more test in complex environment, and compare the result of batch or not batch. good luck. :)

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Mon Mar 12, 2012 8:44 am
by Kojack
One thing to be aware of is that by default all particles in a particle system are culled at once by a single bounding box.
If you use a single particle system and emitters to replace multiple particle systems, then the batch count will drop, but you may have more off screen particles being rendered because the culling is less efficient.
There is a "cull_each" command in the particle script that can turn on per particle culling, but I'm not sure how that will affect performance (way more culling math performed, but way less rendering too. Would probably suck in debug mode).

Re: Deleting a particleEmitter? & Cool method to reduce batc

Posted: Wed Mar 14, 2012 10:06 am
by areay
Thanks for the comments guys.

Kojack; I hadn't considered the culling problem. In my game I've a relatively small map with a free camera which means that the entire scene *could* be in the viewport so it's an unavoidable possibility and not something I'm going to worry about. But, if anyone else is considering doing something like this then that's something they'll need to consider.

xfxsworld; I'm not sure I completely understand what you're saying. Are you suggesting that if any particles are using a material with 'scene_blend alpha_blend' that each particle will be depth-checked against every other particle in every other emitter? I set some materials to be alpha_blend'ed and it all seems fine but I've yet to create a really complicated scene like you suggest.

I sure do appreciate both of your critiques.