Particle Systems and Dynamic Draw Batching inconsistencies

Hi all,

I’m developing a mobile app where I have fireworks effects done using particles systems and am seeing a seemingly strange behaviour in dynamic batching - it is usually not batching together multiple instances of the same particles system (same prefab) listing in the Frame Debugger as cause “Objects have different materials” but sometimes doing it.

Some more details:

  • Unity 2017.3.0f3 in Windows 10 and targetting Android.

  • I’m seeing the same behaviour running in the Editor or in an Android 4.4 tablet.

  • The particles systems are simple expanding balls of particles. Each ball of particles is one Particle System in one GameObject instantiated from a Prefab. All the particles in any single Particle System attached to one GameObject are drawn together, however sometimes multiple Particle Systems are batched in a single Draw Call but sometimes not.
    Example (zoomed in):

  • They’re all using the Mobile/Particles/Additive shader.

  • Even when there are only on screen copies of the same prefab with the same Particles System and the same material, the Frame Debugger will show some batched and most not batched.

  • I’ve seen this both for my own particle materials with my own textures and for Standard Assets materials.

  • I’ve disabled the code in my scripts that alters the ParticleSystems at runtime (change colors and duration) with no difference.

  • I’ve unchecked Size Over Lifetime and Size by Speed from the Particle System config but still get the same strange batching effect.

  • I’ve switched to the Particles/Additive (non-mobile) shader and still get the same result.

  • There doesn’t seem to be any clear reason for why things are dynamically batched - I’ve seen batches of overlapping balls of particles, others non-overlapping from opposite sides of the screen, others with different sizes and others with (seeming) different distances from the camera.

Here’s an example of what I get in the Frame Debugger:

I’ve been poking around trying to figure out why would two objects from the same Prefab with the same Particle System configuration have different materials sometimes but not others, but no joy, so here I am…

:confused:

Any help is most welcome.

What happens when you use a non-transparent shader such as Diffuse?

If I set it to Mobile/Diffuse then the result is one Dynamic Draw Batch for each particle material.

In fact, if in the material configuration I set the Render Queue to Geometry (2000) the result is that all particles for that material will be rendered in a single draw call.

Keep in mind that although my particles are using a transparent shader, since it’s additive blending sort order is wholly unimportant.

Transparent shaders have more cases to consider when batching. It sounds like this is your issue.

I suspected such from what I had found whilst looking around for solution for this problem. However:

  1. The reason for not batching given in the Frame Debugger is “Objects have different materials” even for two consecutive draw calls for the same material.
  2. Even when every single thing in the transparent queue is the exact same material (all of them the same Particle System, instantiated from a single Prefab), it still won’t batch them all together.
  3. Additive Blending is order agnostic - there really is not a single transparent thing in those scenes that needs to be draw in any order versus all the other ones

This game is for tablets and aiming at low-spec ones, so I’m trying to see if I can find myself some GPU-side performance savings, so that I can use the extra breathing space to add a little bit of scenery to the scenes.
Do you have any suggestions if can try to see if I can improve mobile GPU performance in here (I’m looking at other domains for other savings but this post is only about what I found on the draw call batching side), maybe some pointers on documentation about low level things like Render Queues and Transaparent Queue sorting algorithms in Unity?

Interestingly, If in one of the Particle Materials I put the Render Queue to be Transparent+X (I’ve tested X=1 and X=50) then all the particles of all the Particle Systems using that material will be Dynamically Batched into a single call, even whilst all the other particles still in Render Queue 3000 will NOT.

Furthermore, if I change the Render Queue of the other Particle Materials in the same way:

  1. Those which have no other Material in the same Render Queue will have all the particles in all particle systems batched in ONE draw call.
  2. Those for which there are two or more materials being rendered in the same Render Queue will, as before, have maybe some batches but not for most particles.

So the solution seems to be to manually force each Particle Material into their own Transparent Render Queue, different from the ones for all others.
I suspect that by doing this I am forcing my own sorting order for each material, thus allowing the Dynamic Batching to find all instances which use the same material one after the other in a single block and thus batch them all.

:slight_smile:

Interesting. It’s worth filing a bug report regarding the batching message, maybe we can improve that.

In my case particles that are not using trials are batched in one call. And having trails enabled makes every single system to be bached separately.

The solution was to set Render Queue for a trails material to 3001 while leaving the main material at 3000. (2018.3.7f1)

2 Likes

Were they using different materials?
https://docs.unity3d.com/Manual/DrawCallBatching.html