How can batchNode ParticleEmitter?

how can bachNode ParticleEmitter?
i have too much ParticleEmitter!

i would rather try lower particle amount. for example Fire particleEmitter can use 10000 particles or 10 particles. In your “far-distance particles” i would rather target lower particle amount.

So how many particles you use each for this particle emitters? Generally i could do very similar effect with like 100-400 particles on screen like yours that should work fine.

but if you make 1pixel particle so on screen you could have 10000 particles that is too much for game like this.

i have too much ParticleEmitter!

so i think not too much ParticleEmitter, but Particles generated by ParticleEmitters.

how can use more particleemitter? i cant dynamic manage my particleemitter in far-distance or close-distance , becase too troublesome! i just make a rts game i need all thing in rootNode

you can, like i said above

I’m not sure if you can instance particles using an instance node and setting the particle material to instanced.

Seems like you should be able to in theory.

But, I mean, that’s game development. Figuring out how to work the smoke and mirrors to make it seem like more is happening than is.

You can’t just throw 1000s and 1000s of things in the root node and expect that to work well.

You cannot normally instance particle emitters, and batching is also not possible.

If the issues is the number of particles, you can use point particles by creating an emitter with Type.Point and use mat.setBoolean("PointSprite", true); in the particle material. This will use one point for each particle, instead of a quad.
See example here jmonkeyengine/TestPointSprite.java at master · jMonkeyEngine/jmonkeyengine · GitHub

If you think your issue is the number of emitters, that means the number of drawcalls, (that is what you reduce with instancing or batching), since every emitter is one single mesh, you can try to use the same emitter to emit particles at different locations by setting ‘setInWorldSpace(true)’ and moving it around, this will reduce the drawcalls.

So, each particle emitter would look exactly the same. Not sure that’s the desired effect but with some hacking (and writing one’s own particle emitter) it could work. They all start at the same time, stop at the same time, be exact copies of one another.

Frankly, even partitioning the root node into child nodes by space would be better than nothing. The “I don’t even want to fix my scene” approach probably isn’t going to go far, though.

I would first try to group your emitters into nodes as pspeed suggested: One for northwest, one for southwest etc. or even more groups in a grid. It will allow for more efficient culling of unneeded objects, especially if your maps are large. You don’t have to give those nodes a translation.
Because if you batch the emitters, you will lose the culling and it will always try to render all particles.

Depending on what you need, batching could be easy or very hard.

  • Use one single ParticleEmitter with a custom EmitterShape which will define the position of newly spawned particles.
  • Make a class that manages the individual spawn points. Instead of creating many ParticleEmitters, you use this class to register spawn points.
  • Distribute the particles in the EmitterShape over the registered spawn points.

If you want to use different particle-per-second values for each spawn point, you need to implement a different distribution: Darts, Dice, and Coins
The easy method in short:

  • Each spawn point has its own particle-per-second value (and other attributes if needed).
  • Think of it as the size of one field on a darts board (one-dimensional). The goal is to throw random darts at this board.
  • Put “SpawnPoint” objects into an array. This object additionally has a ppsSum field. It holds the sum of particle-per-second values of all the SpawnPoint objects to the left, and includes its own value.
  • Since the ppsSum value will naturally grow to the right, the array is sorted and this enables binary search.
  • Use ParticleEmitter.setParticlesPerSec() and set the value to the total ppsSum

To spawn particles:

  • Generate a random value from 0 to the total particle-per-second values across all spawn points (ppsSum + last element’s pps)
  • Do a binary search on the array to find the correct spawn point

It’s surprisingly fast. Our implementation of the distribution takes 70ns per particle with 1000+ emitters and we use it to spawn multiple thousands of particles per second in VR. With an OpenCL implementation of a particle emitter though. The binary search takes around 6 steps.
There’s a more optimized version for this distribution at the bottom of the linked article, but it takes more time to initially build the table with the probabilities.

Unifying particle emitters into one mesh might cause issues with sorting and transparency. If you use multiple types of batched particle emitters, one type of particle will always be drawn above the other types since no sorting takes place across emitters and particles are usually rendered with depth-write disabled.
To solve this you’d have to batch all types of particles into one. This is sometimes referred to as “Uber Shader”.

Also, jme’s ParticleEmitter is a bit limited and for example doesn’t support an individual size for each particle. You might get around that with the getParticles() of ParticleEmitter and the overwrite the size attribute manually - or something like that.

Also, AFAIK, ParticleEmitter.setInWorldSpace(true) is still buggy and might modify your positions.