Search Unity

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