Deleting a particleEmitter? & Cool method to reduce batches

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
areay
Bugbear
Posts: 819
Joined: Wed May 05, 2010 4:59 am
Location: Auckland, NZ
x 69

Deleting a particleEmitter? & Cool method to reduce batches

Post 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
User avatar
xfxsworld
Gnoblar
Posts: 13
Joined: Wed Feb 29, 2012 10:55 am

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

Post 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...
User avatar
areay
Bugbear
Posts: 819
Joined: Wed May 05, 2010 4:59 am
Location: Auckland, NZ
x 69

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

Post 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
User avatar
xfxsworld
Gnoblar
Posts: 13
Joined: Wed Feb 29, 2012 10:55 am

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

Post 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...
User avatar
areay
Bugbear
Posts: 819
Joined: Wed May 05, 2010 4:59 am
Location: Auckland, NZ
x 69

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

Post 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?
User avatar
xfxsworld
Gnoblar
Posts: 13
Joined: Wed Feb 29, 2012 10:55 am

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

Post 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. :)
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

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

Post 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).
User avatar
areay
Bugbear
Posts: 819
Joined: Wed May 05, 2010 4:59 am
Location: Auckland, NZ
x 69

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

Post 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.
Post Reply