Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Culling -> Recalc Bounds

Discussion in 'General Graphics' started by iivo_k, May 22, 2016.

  1. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    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?

    RecalcBounds.png
     
  2. LeonH

    LeonH

    Joined:
    Oct 15, 2014
    Posts:
    92
    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.
     
  3. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    If a skinned mesh renderer has update when offscreen it then needs to update its bounds every frame. Does it need to be updating when offscreen?
     
  4. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    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?
     
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Try setting LocalBounds. I'm not near the source code to say for sure but this may work.
     
  6. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    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.
     
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    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?
     
  8. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    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?

    GameView.jpg SceneView.jpg CullingSpike.jpg

    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.
     
    Last edited: Jun 11, 2016
  9. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Yeah create an example and file a bug report about the animations still updating offscreen.
     
  10. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    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.
     

    Attached Files:

  11. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    Well, I also created bug report 805267 with the culling example. Hopefully something can be done about the performance.
     
  12. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    Using Graphics.DrawMesh is a workaround, it avoids Culling -> RecalcBounds. Overall performance seems about the same as with MeshRenderer but there are no spikes.
     
    mh114 likes this.
  13. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    Nope, scratch that. While it does avoid the culling, having to call Graphics.DrawMesh each frame is slower.