Search Unity

Graphics.DrawMeshInstanced() and culling, the how and why

Discussion in 'Scripting' started by hausmaus, Feb 22, 2019.

  1. hausmaus

    hausmaus

    Joined:
    Dec 9, 2011
    Posts:
    105
    I am running into issues with vertex-shader displaced geometry being culled by the camera when rendered by Graphics.DrawMeshInstanced(), similar to the issue expressed in other threads like these:
    https://forum.unity.com/threads/instancing-and-culling-make-it-stop.511374/
    https://www.reddit.com/r/Unity3D/comments/7okgkj/help_with_instancing_and_frustrum_bounds/

    From the docs: https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstanced.html

    Use this function in situations where you want to draw the same mesh for a particular amount of times using an instanced shader. Meshes are not further culled by the view frustum or baked occluders, nor sorted for transparency or z efficiency.

    The only suggestion that I have seen which almost worked is to set the Y value of the object being deformed (several tessellated patches forming a terrain) to match the camera's Y. But the most intuitive solution was to set the Y component of mesh.bounds to be enormous, which didn't work.

    Ultimately, I just set some of the un-displaced mesh vertices to very high and low Y values, forcing the bounds issue in the vertex buffer and not just assigning a big bounds volume, which does seem to work (and solves the problem where matching the mesh to game camera Y just gets it culled in the Editor as soon as the game camera leaves the Editor camera FoV, but it's still pretty hacky). I'm assuming there is a better way!

    My real question is what, exactly, is Unity basing its culling on in this case? The docs say it doesn't do frustum or occlusion culling. The mesh bounds are set to something that should never not intersect the frustum. But the objects are still not drawn, seemingly when the camera would have lost visibility of the un-displaced source mesh. Is there another type of culling that I'm not accounting for, that still respects the mesh bounds creating by having these hugely high/low Y values in the source mesh to force the issue? Also, what does mesh.bounds do if not this?

    If not, would it be possible to get the docs updated, and/or to have this labeled as a bug? DrawMeshInstanced, and really all of the rendering tools, can be extremely powerful if they work predictably.

    Thanks for any insight,
    Adrian
     
    Last edited: Feb 22, 2019
    deus0, PrimalCoder, Dinamytes and 3 others like this.
  2. SLGSimon

    SLGSimon

    Joined:
    Jul 23, 2019
    Posts:
    80
    This is biting me now, I have a tiny cube getting instanced 1000s of times and they're all disappearing!
    Calls to this should not be getting culled in any way!
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    If the meshes are getting culled, then either the docs are wrong, or there's a bug in the code. Create a bug report!
     
  4. tim12332000

    tim12332000

    Joined:
    Jun 15, 2017
    Posts:
    20
    What is "un-displaced mesh vertices" mean ?
     
  5. tim12332000

    tim12332000

    Joined:
    Jun 15, 2017
    Posts:
    20

    Can you post your code? Thanks
     
  6. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    It was the bounds for me, when the bounds was too small it culled the objects. I wanted to use the bounds for culling then, and then the docs said nope you can't cull using the command. So how do you cull the objects. Maybe through instancing in chunks so the CPU can handle it?