Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Is it actually possible to dynamically batch 300+ vertice mesh ?

Discussion in 'General Graphics' started by NoseKills, Feb 4, 2015.

  1. NoseKills

    NoseKills

    Joined:
    Jun 4, 2013
    Posts:
    25
    I'm gonna take one more angle at my problem of getting dynamic batching to work.

    Recap: This answer lets you understand 900 is the max vertice count that can be batched dynamically.
    The actual documentation doesn't deny nor confirm it.

    But can anyone make these meshes actually batch ? The script should work by just slapping it on the camera in an empty scene.

    Looks like 300 is actually the hard limit (double click on any of the meshes on the created prefabs to see vertice count). Or do i have to change something in project settings to go over 300 ? You can reduce vertice count by reducing "quadsW" to 12 -> they will batch.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class VertexTest : MonoBehaviour
    7. {
    8.     void Start ()
    9.     {
    10.         const int quadsW = 13;
    11.         const int quadsH = 6;
    12.  
    13.         List<Vector3> verts = new List<Vector3>();
    14.         List<int> tris = new List<int>();
    15.  
    16.         for (int qx = 0; qx < quadsW; qx++)
    17.         {
    18.             for (int qy = 0; qy < quadsH; qy++)
    19.             {
    20.                 makeSquare(qx, qy, 0, verts, tris);
    21.             }
    22.         }
    23.  
    24.         Mesh m = new Mesh();
    25.         m.Clear ();
    26.         m.vertices = verts.ToArray();
    27.         m.triangles = tris.ToArray();
    28.         m.uv = null;//new Vector2[verts.Count];
    29.         m.uv1 = null;//new Vector2[verts.Count];
    30.         m.uv2 = null;//new Vector2[verts.Count];
    31.         m.colors32 = null;//new Color32[verts.Count];
    32.         m.colors = null;//new Color[verts.Count];
    33.         m.normals = null;//new Vector3[verts.Count];
    34.         m.Optimize ();
    35.         m.RecalculateNormals ();
    36.  
    37.         Material mat = new Material(Shader.Find("Mobile/VertexLit"));
    38.  
    39.         const int gameobjectsW = 4;
    40.         const int gameobjectsH = 4;
    41.        
    42.         for (int x = 0; x < gameobjectsW; x++)
    43.         {
    44.             for (int y = 0; y < gameobjectsH; y++)
    45.             {
    46.                 GameObject go = new GameObject(x+", "+y);
    47.                 go.transform.position = new Vector3((x*quadsW) + x, (y*quadsH) + y);
    48.  
    49.                 MeshRenderer mr = go.AddComponent<MeshRenderer>();
    50.                 MeshFilter mf = go.AddComponent<MeshFilter>();
    51.                 mf.sharedMesh = m;
    52.                 mr.castShadows = false;
    53.                 mr.receiveShadows = false;
    54.                 mr.sharedMaterial = mat;
    55.             }
    56.         }
    57.  
    58.         Camera.main.transform.position = new Vector3(gameobjectsW * (quadsW+1), gameobjectsH * (quadsH+1), -50 ) / 2f;
    59.     }
    60.    
    61.     void makeSquare(int x, int y, int z, List<Vector3> verts, List<int> tris)
    62.     {
    63.         int statrCount = verts.Count;
    64.         verts.Add (new Vector3(x, y, z));
    65.         verts.Add (new Vector3(x, y+1, z));
    66.         verts.Add (new Vector3(x+1, y+1, z));
    67.         verts.Add (new Vector3(x+1, y, z));
    68.  
    69.         tris.Add(statrCount);
    70.         tris.Add(statrCount+1);
    71.         tris.Add(statrCount+2);
    72.  
    73.         tris.Add(statrCount);
    74.         tris.Add(statrCount+2);
    75.         tris.Add(statrCount+3);
    76.     }
    77. }
    78.  
    79.  
     
    Last edited: Feb 4, 2015
  2. Zenchuck

    Zenchuck

    Joined:
    Jun 2, 2010
    Posts:
    279
    Vertex data can mean a lot of things. Can carry more than just position information - things like colour, uv1, uv2, tangent, normal etc. etc.

    Not sure if that would make a difference but maybe worth looking at?
     
  3. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,102
    Are you using the batching to combine meshes that change all the time ore do you just like to combine stuff that instantiate at run-time?
    If the meshes do not change / move you can use the StaticBatchingUtility to combine them at run-time.
    Then i acts like if you would set it to be batching static.

    In all cases , thanks for sharing your research.
     
    theANMATOR2b likes this.
  4. NoseKills

    NoseKills

    Joined:
    Jun 4, 2013
    Posts:
    25
    @Zenchuck I'm setting those in my code snippet (edited) but they don't seem to affect anything :-/

    The sources I linked say the vertex amount that can get batched depends on the shader, not the mesh and it is
    900 / [number of attributes used by the shader]. "Shader attributes" being the ones you mention: position, normal, tangent, uv...

    This screenshot is not from my shader. I'm using one that only lists "position" in used attributes


    @fffMalzbier I'll be having 30+ pre-compile generated Voxel enemies on the screen, made out of ~5 different meshes and I was looking for dynamic batching to give me 5 draw calls instead of 30+. I'll be dynamically generating stuff only when stuff dies and disintegrates. Luckily now that my design has clarified, I noticed I can make my meshes under 300 verts by removing back and upper faces since the camera will never see them. Now they batch as I want them to.

    Actually I have never tried that StaticBatchingUtility. Thanks for the tip. It'll come in handy with the static obstacles probably.
     
    theANMATOR2b likes this.
unityunity