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

Vertex count vs. Dynamic batching

Discussion in 'General Graphics' started by NoseKills, Jan 26, 2015.

  1. NoseKills

    NoseKills

    Joined:
    Jun 4, 2013
    Posts:
    25
    I'm working on a game with procedurally generated voxel enemies. I made a test mesh to see what the performance was like. I quickly noticed that i was getting 1 draw call/mesh even with a fairly simple mesh.

    I read about Dynamic batching rules here and here. Based on this info I figured the problem must be because of either the shader I'm using and/or the Vertex count. I cut my generated mesh from 440 vertices to under 300 and TADDAA, 1 draw call/mesh.

    The problem is I have no idea why. I'm using as simple a shader as I could find in Unity's Shader Tutorials. And if I generate another kind of mesh with 900 vertices, I can get that to be batched without problems.

    So mesh A with 900 vertices and Material M does get batched but in the same scene Mesh B with 440 vertices and Material M doesn't get batched.

    I made a test app to try this out.

    If I use "option A", to create a 900 vert, 100 triangle mesh with my simple shader, and generate 10 of these objects, I'm seeing 1 draw call. (why does Unity say 100 triangles when it should have 300 ?.. anyways...)

    If I use "option B" to create 10 of my 440 vert Meshes, i get 10 draw calls (same material)
    Code (CSharp):
    1.     public static Mesh _Mesh;
    2.     public static Material _Mat;
    3.  
    4.     void Awake()
    5.     {
    6.         if (_Mat == null) _Mat = Resources.Load<Material>("TestMat");
    7.  
    8. //        option A
    9. //        if (_Mesh == null) _Mesh = createMesh();
    10.  
    11. //        option B
    12.         if (_Mesh == null) _Mesh = Resources.Load<Mesh>("test1_Mesh");
    13.  
    14.         MeshRenderer mr = gameObject.AddComponent<MeshRenderer>();
    15.         mr.receiveShadows = false;
    16.         mr.castShadows = false;
    17.         MeshFilter mf = gameObject.AddComponent<MeshFilter> ();
    18.  
    19.         mf.sharedMesh = _Mesh;
    20.         mr.sharedMaterial = _Mat;
    21.     }
    22.  
    23.     Mesh createMesh()
    24.     {
    25.         int vertCount = 300 * 3;
    26.  
    27.         Vector3[] verts = new Vector3[vertCount];
    28.         for (int i = 0; i < vertCount; i+=3)
    29.         {
    30.             verts [i] = new Vector3 (0, 10, i);
    31.             verts [i+1] = new Vector3 (10, 0, i);
    32.             verts [i+2] = new Vector3 (-10, 0, i);
    33.         }
    34.         int[] tris = new int[vertCount / 3];
    35.         for (int i = 0; i < tris.Length; i++)
    36.         {
    37.             tris[i] = i;
    38.         }
    39.  
    40.         Mesh m = new Mesh();
    41.         m.Clear ();
    42.         m.vertices = verts;
    43.         m.triangles = tris;
    44.         m.RecalculateNormals ();
    45.         m.Optimize ();
    46.         return m;
    47.     }
    What gives ? Is there more to the batching than the docs tell ?
    My test case should rule out any other variables since nothing is scaled, there's no lighting or shadows etc.
    Am I just having a brain fart...

    Shader I'm using in both cases.

    Code (CSharp):
    1. Shader "VertexLitTest" {
    2.     Properties {
    3.         _Color ("Main Color", Color) = (1,1,1,0.5)
    4.     }
    5.     SubShader {
    6.         Pass {
    7.             Material {
    8.                 Diffuse [_Color]
    9.             }
    10.             Lighting Off
    11.         }
    12.     }
    13. }
    14.  
     
    Last edited: Feb 4, 2015