Search Unity

Question DrawMeshInstanced and Culling

Discussion in 'General Graphics' started by minDog, Jul 14, 2022.

  1. minDog


    Oct 21, 2021
    I'm working on a very lightweight scriptable rendering pipeline, and I'm trying to use DrawMeshInstanced to render a lot of geometry. My question is regarding frustrum culling of DrawMeshInstanced geometry. In the docs it says:

    Use this function in situations where you want to draw the same mesh for a particular amount of times using an instanced shader. Unity culls and sorts instanced Meshes as a group. It creates an axis-aligned bounding box that contains all the Meshes, calculates the center point, then uses this information to cull and sort the Mesh instances. Note that after culling and sorting the combined instances, Unity does not further cull individual instances by the view frustum or baked occluders. It also does not sort individual instances for transparency or depth efficiency.

    . But in my case it absolutely does cull them one-by-one, and not as a "group" as the doc says, unless I misunderstand something.

    I have thousands of meshes rendered and when I move the camera around, to point it away from geometry, it reduces the batches to zero, and when I move up, to see the whole map, it rightly displays the high number of batches. So what is going on? I'm not doing any culling in the scripts.

    In my SRP I have the basic culling configured:

    Code (CSharp):
    1. camera.TryGetCullingParameters(out var cullingParameters);
    2. _cull = context.Cull(ref cullingParameters);
    3. context.DrawRenderers(_cull, ref drawingSettings, ref filteringSettings);
    And for drawing the meshes I literally just loop through all matrices and call
    Code (CSharp):
    1. Graphics.DrawMeshInstanced
    My shader and SRP support instancing, and rendering, for now, is done through a bare-bones unlit shader.

    So my questions are: are the results of DrawMeshInstanced culled or not? If so, are they frustrum culled? If so, are they frustrum culled one-by-one, as defined by their matrix and mesh's bounds?

    I use Unity 2022.1.3f1
    Last edited: Jul 14, 2022
  2. c0d3_m0nk3y


    Oct 21, 2021
    Just to make sure, you are replacing N DrawMesh calls with a single DrawMeshInstanced call (it would certainly do that if you'd just pass a single matrix per DrawMeshInstanced call, but the entire idea of instancing is to do it in a single draw call)?

    I think, Unity has all the information it needs to do culling per instance. So it's possible. I'd suggest taking a RenderDoc capture (frame debugger might work too) so see whether it is reducing the number of instances.