I’m profiling a top down scene with a lot of objects that have SkinnedMeshRenderers and RigidBodies and I’m having trouble getting the performance where I want it to be, so I’m trying to shave off precious milliseconds where ever I can.
Frustum culling didn’t work properly with the Animators, so I’m using CullingGroups to disable the Renderers and Animators when offscreen. I’ve set the Animator’s culling mode to Always Animate and SkinnedMeshRenderer’s Update When Offscreen to true, since I’m handling that manually. Occlusion culling is turned off too.
Now when I’m profiling, there’s Camera.Render → Culling → Recalc Bounds taking a millisecond with 500 objects, with 1000 objects it’s up to 2ms. I’m not really sure what bounds would need to be calculated here every frame, could be related to the skinned anims, since a test scene with 2000 moving cubes spends 0.66 ms on Recalc Bounds. Does anyone have an idea what that is and can I somehow get rid of it?
We’re also seeing high costs in “Recalc Bounds”. Would be nice if someone from Unity could comment on what this actually represents and what factors in the scene are influential to how it scales.
Well, like I said, the frustum culling didn’t work properly in the scene for some reason so I turned it off and manually disabled the renderers when offscreen.
Anyway, I did away with SkinnedMeshRenderers and instead baked the meshes which I set manually to MeshFilters. Still didn’t affect Culling.RecalcBounds. If I fully disable the animations (and in another test scene with a bunch of cubes moving on the screen) RecalcBounds is way faster, so I assume it’s because the bounds are recalculated whenever the mesh changes. I guess my question is, is it possible to set some static bounds for a MeshRenderer, which are never recalculated?
I’m no longer using SkinnedMeshRenderers, since the animation system itself (even legacy) doesn’t have good enough performance for several hundreds units. I’ve baked the meshes, which I manually set to the MeshFilters of the objects, which is very fast. I don’t see any way to set the bounds to regular MeshRenderers though.
I’m not sure if disabling the culling system completely would cause other problems and thus isn’t possible (maybe it’s needed for lighting or something), but maybe being able to set a big enough bounding box that never changes size and isn’t rotated could help.
You can set the bounds for the mesh before you assign it to the mesh filter - http://docs.unity3d.com/ScriptReference/Mesh-bounds.html
You can’t disable the culling system and its not something you should disable, your performance would be horrible.
What do you mean by the frustum culling didn’t work properly?
That had no effect on Culling.RecalcBounds unfortunately. The meshes already had bounds anyway and I checked that they don’t change.
In my scene everything with an active renderer is on the screen (since I use CullingGroups to control them), so I would think frustum and occlusion culling aren’t that beneficial?
Culling.RecalcBounds spikes whenever the meshes are changed on the objects.
Should I try to make a simpler example project, something like a couple thousand cubes in the gameview, with the mesh constantly changing between cube and sphere?
Animators would keep on animating even if the object was way off-screen (checked this by seeing how many Animator.update calls there was on the profiler). I noticed when I moved the camera to the right away from the objects, I could pinpoint an exact position when most of the animators were suddenly culled. Didn’t investigate any further though, since I needed to use CullingGroups anyway to disable stuff on offscreen objects and Mecanim is way too heavy for what I’m trying to do.
Attached is a very simple example project. In TestScene there’s a GameObject called Instantiator that creates 10000 gameobjects, positions them randomly in an area and changes their meshes every frame. The more meshes there are and the more complex they are, the longer RecalcBounds takes.
Edit: I used 5.4.0b21 btw. but it’s the same thing in 5.3.
I don’t have the scene with the Animator problem anymore since I’ve moved past Mecanim, but for what it’s worth it didn’t happen in other scenes back then.
Using Graphics.DrawMesh is a workaround, it avoids Culling → RecalcBounds. Overall performance seems about the same as with MeshRenderer but there are no spikes.