How to optimize ParticleSystem.UpdateRendererBoundingVolumes?

In our Android game, we have very few Particle Systems (like 10 and 8 of them are the same), but sometimes, UpdateRendererBoundingVolumes spikes up to 1ms+, it usually is around 0.3ms.

I assume it uses the particle positions to compute a bounding box that encapsulates every particle? Is it possible to specify this at edit time instead? I know the max volume of a ParticleSystem at edit time quite often and could tweak it to contain all the particles without having to compute it at runtime.

Do I have a way to get rid or optimize UpdateRendererBoundingVolumes?

No this is not possible. We did prototype a version to do this a few years ago but the performance benefit was tiny and the possibility for error was high. An incorrect bounding box will cause many problems.

How many particles does each of your systems contain? What sort of modules are they using? If you are able to use procedural mode then the bounding calculations should be much faster. We only use every particle positions when in non-procedural. https://blogs.unity3d.com/2016/12/20/unitytips-particlesystem-performance-culling/

1 Like

Hi Karl, thanks for the quick help.

I didn’t know of the help icon, that’s genius!
6217344--683613--upload_2020-8-18_11-42-3.png

6217344--683616--upload_2020-8-18_11-53-46.png

The ParticleSystems contain mostly 9-11 particles, they’re clamped to a maximum of 20 particles and I’ve 8 of those ParticleSystems.

They’re used to emit dust behind a racer. I understand that due to the world-space position changes, computing the bounding box is from advantage.

My approach would be to make the BB large enough that no popping occurs. Basically trade rendering a few more triangles for a quicker UpdateRendererBoundingVolumes update. Then profile if the trade actually improves performance.

The other particle system is attached to the camera and used to emit leaves/pollen around the player. It’s also using world-space and distance-based emission.

I guess a workaround could be to use local space simulation, place it at 0,0,0 and then use ParticleSystem.Emit(position) and write the distance-based emission myself?

1ms for 9-11 particles seems very high. UpdateRendererBoundingvolumes does not just calculate the bounds, I expect that would be very fast for 9-11 particles. It does some extra work around transform/hierarchy changes and this is likely what is taking most of the time. I don’t believe the workaround you suggest would help.
How are you moving the system? Is it under a big hierarchy?

From what you have described it should not be taking this long. If possible could you file a bug report so we can take a look, maybe there’s something we can optimize or fix.

1 Like

Thanks again for the quick help, much appreciated!

racer_5_npc is a root object and fx_dust is the particle system. I move the racer_5_npc gameobject via transform.position = newValue. The game does not use Physics (it’s disabled) or any rigidbody if that question should come up.

6217563--683649--upload_2020-8-18_12-47-4.png

6217563--683652--upload_2020-8-18_12-49-35.png

I just saw “Emitter Velocity” is set to “Rigidbody”, even though there is no RB. Could this cause issues? I should probably switch it to Transform.

Would it help if I pull the ParticleSystem out of the hierarchy, make it a root object, and move it myself, rather than it being moved implicitly via the parent?

BTW I’m still on Unity 2018.4.22f1.

We would need a bug report to really say whats going on. Could be something with the transforms.
Changing velocity move from Rigidbody to Transform should help your performance a little. Internally we do a lookup for a Rigidbody/Rigidbody2D each frame. We do have an improvement to this in works but its unlikely to make it to 2018.4, so change it over :slight_smile:

2 Likes