Search Unity

Question Drawing millions of triangles (single mesh vs instancing)

Discussion in 'General Graphics' started by itsjase, Nov 13, 2022.

  1. itsjase

    itsjase

    Joined:
    Apr 18, 2017
    Posts:
    4
    I've recently been working on a project for which I need to draw millions of meshes (single triangles) at positions from a compute buffer.

    The method I'm using is DrawPrimitives, but I've noticed using instancing seems to almost half performance at larger numbers of triangles (32 million), compared to when I just pass everything through as one instance, and I'm trying to work out if there's a reason.

    Examples below:

    Method 1 (~30fps) - As instances, indexing by vertexID
    Code (CSharp):
    1. // C# code
    2. Graphics.RenderPrimitives(rp, MeshTopology.Triangles, 3, numBoids);
    Code (Shader):
    1. // Shader code
    2. v2f vert(uint vertexID : SV_VertexID, uint instanceID : SV_INSTANCEID) {
    3. Boid boid = boids[instanceID];
    4. v2f o;
    5. float3 pos = _Positions[vertexID];
    6. rotate2D(pos.xy, boid.vel);
    7. o.vertex = UnityObjectToClipPos((pos * _Scale) + float4(boid.pos.xy, 0, 0));
    8. return o;
    9. }

    Method 2 (~70 fps) - As one large mesh, indexing by (vertexID % vertexCount)
    Code (CSharp):
    1. // C# code
    2. Graphics.RenderPrimitives(rp, MeshTopology.Triangles, numBoids * 3);
    Code (Shader):
    1. // Shader code
    2. v2f vert(uint vertexID : SV_VertexID) {
    3. uint instanceID = vertexID / 3;
    4. Boid boid = boids[instanceID];
    5. v2f o;
    6. float3 pos = _Positions[vertexID - instanceID * 3];
    7. rotate2D(pos.xy, boid.vel);
    8. o.vertex = UnityObjectToClipPos((pos * _Scale) + float4(boid.pos.xy, 0, 0));
    9. return o;
    10. }
    I'm still quite new to shader programming in general so any info on why this performance difference exists would be greatly appreciated.
     
    Last edited: Nov 13, 2022
    OhneHerz, cecarlsen and olavrv like this.