Search Unity

Why is mesh.combinemeshes useless now?

Discussion in 'Scripting' started by applejuices, Dec 22, 2014.

  1. applejuices

    applejuices

    Joined:
    Nov 20, 2013
    Posts:
    80
    Problems i have encountered:
    • Meshes dont keep their submesh material atributes. all submeshes use the last material.
    • Meshes combine into each other, cause entire faces to be rendered from one mesh to another.
    • Shadows are rendered by mesh, not vertex. So if you have a large map, this is useless.
    • Meshes sometimes dont even combine properly. Causing them to be ripped to shreds and combined into other meshes.
    • Increases verticies like crazy, my 700k verts went up to 2.8mil verts.
    • NEW: also meshes keep their deformed shape when I stop the game. This isnt perminent but it is annoying.
    I have about 1.3k objects in a map, I combine each object that is equal to one another together(trees with trees, not trees with building and cars). But all of the above happens. Actually decreasing performance. And im using this because dynamic batching isnt an option at all. 9k calls, 4k of those 9k are batched(causing a bit of an overhead). How ever the only good to come from this, 5k draw calls nd 4k others batched, is now reduced to 250 draw calls and none batched.(about 20-30 tiems better). So this script only works well if there are no shadows.
    oh and if you want a copy of the script or can find problems here it is:


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5.  
    6. [RequireComponent(typeof(MeshRenderer))]
    7. public class Stuff : MonoBehaviour {
    8.  
    9.     void Start(){
    10.         Check ();
    11.    
    12.     }
    13.     void Check(){
    14.         MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
    15.         List<MeshFilter> Newfilt = new List<MeshFilter>();
    16.         foreach (MeshFilter filt in meshFilters) {
    17.             if(filt.renderer.materials[0].name == meshFilters[0].renderer.materials[0].name){
    18.                 Newfilt.Add(filt);
    19.             }
    20.         }
    21.         BatchObjs (Newfilt);
    22.         print ("Checking done, " + Newfilt.Count + " objects with same first mat, going to batch them!");
    23.    
    24.     }
    25.  
    26.     void BatchObjs(List<MeshFilter> meshFil) {
    27.         GameObject meshon = new GameObject();
    28.         MeshFilter[] meshFilters = meshFil.ToArray();
    29.         CombineInstance[] combine = new CombineInstance[meshFilters.Length];
    30.         List<MeshFilter> newfilts = new List<MeshFilter> ();
    31.         int i = 0;
    32.         while (i < meshFilters.Length && meshFilters[0].mesh.vertices.Length * i < 64500) {//
    33.             newfilts.Add(meshFilters[i]);
    34.             combine[i].mesh = meshFilters[i].sharedMesh;
    35.             combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
    36.             //following is attributes to combine;
    37.             combine[i].mesh.vertices = meshFilters[i].mesh.vertices;
    38.             combine[i].mesh.triangles = meshFilters[i].mesh.triangles;
    39.             combine[i].mesh.uv = meshFilters[i].mesh.uv;
    40.             combine[i].mesh.uv1 = meshFilters[i].mesh.uv1;
    41.             combine[i].mesh.uv2 = meshFilters[i].mesh.uv2;
    42.             combine[i].mesh.normals = meshFilters[i].mesh.normals;
    43.             Destroy(meshFilters[i].mesh);
    44.             Destroy(meshFilters[i].gameObject);
    45.             meshFilters[i].gameObject.SetActive(false);
    46.             i++;
    47.         }
    48.         //
    49.         meshon.gameObject.AddComponent<MeshFilter> ();
    50.         meshon.gameObject.AddComponent<MeshRenderer> ();
    51.         meshon.GetComponent<MeshFilter>().mesh = new Mesh();
    52.         meshon.GetComponent<MeshFilter>().mesh.CombineMeshes(combine,true);
    53.         Material[] Mats = new Material[meshFilters[0].renderer.materials.Length];
    54.         for (int i2 = 0; i2 < meshFilters[0].renderer.materials.Length; i2++) {
    55.             Mats[i2] = meshFilters[0].renderer.materials[i2];
    56.         }
    57.         meshon.renderer.materials = Mats;
    58.  
    59.         if (GetComponentsInChildren<MeshFilter> ().Length > 0) {
    60.             Invoke("Check",.2f);
    61.         }
    62.     }
    63. }

    Below is without my batching. 23 fps, and its laggy and the meshes are saved from the last combine, but they are rendered as reg meshes anyways

    Below, after doing the script. If you were on the ground you'd get 18 fps, cause of shadows(calculate per mesh, not vertices) , rendered is much smaller but its will laggy. as well as the meshes deforming into each other(as you can see with all of the red and green lines, which are car hood and tree leaves makeing faces deforming and combining) Also buildings are black or blue because thets their last material, and they dont assign to submeshes.
     
    Last edited: Dec 22, 2014
  2. applejuices

    applejuices

    Joined:
    Nov 20, 2013
    Posts:
    80
    No one else runs into this problem?
     
  3. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You probably don't want to combine meshes like this in the first place. Combining all the "like" objects into a single mesh is going to cause Unity to process that entire mesh when it needs to draw one of those objects. So if you combine all the trees into a single mesh and I'm looking at one leaf then all of the trees on the map need to be processed for rendering instead of just the tree that I'm looking at.

    If this is a city and the camera is at ground level you'll probably get a lot more mileage out of some kind of occlusion culling.
     
  4. applejuices

    applejuices

    Joined:
    Nov 20, 2013
    Posts:
    80
    You are right, I tried occlusion culling(my own) before, but for some odd reason, I stopped.i iwll try to do it again. Also one more thing, how would I get all objects within a cube?