zl程序教程

您现在的位置是:首页 >  其它

当前栏目

Unity Mesh网格合并

合并 Unity 网格 Mesh
2023-06-13 09:11:38 时间

Mesh网格合并通常是优化中常用的小手段,目的是为了减少drawcall,大量的drawcall会造成CPU的性能瓶颈。例如下图中船只里的钢材货物,由诸多钢材模型堆砌而成。

我们将其放在一个空场景里查看Stats信息,可见Batches指数为94

下面我们进行网格合并,将所有的钢材合并为一个Mesh,代码如下:

//绘制Button按钮
if (GUILayout.Button("Combine"))
{
    //用于存储材质球
    List<Material> materials = new List<Material>();
    List<CombineInstance> combineInstances = new List<CombineInstance>();
    for (int i = 0; i < Selection.objects.Length; i++)
    {
        GameObject gameObject = Selection.objects[i] as GameObject;
        //如果物体为空或物体不存在MeshFilter组件或Mesh网格为空则跳出
        if (gameObject == null) continue;
        MeshFilter filter = gameObject.GetComponent<MeshFilter>();
        if (filter == null || filter.sharedMesh == null) continue;
        //展示进度
        EditorUtility.DisplayProgressBar("Mesh Combine", "Combine " + filter.sharedMesh.name, (float)i + 1 / Selection.objects.Length);
        combineInstances.Add(new CombineInstance()
        {
            mesh = filter.sharedMesh,
            transform = filter.transform.localToWorldMatrix
        });
        MeshRenderer renderer = gameObject.GetComponent<MeshRenderer>();
        materials.AddRange(renderer.sharedMaterials);
    }
    EditorUtility.ClearProgressBar();
    //创建新的物体用于挂载合并后的网格
    GameObject combine = new GameObject("Combined Mesh");
    MeshFilter meshFilter = combine.AddComponent<MeshFilter>();
    meshFilter.mesh = new Mesh { name = $"Combined Mesh {Guid.NewGuid()}" };
    meshFilter.sharedMesh.CombineMeshes(combineInstances.ToArray(), mergeSubMeshes);
    MeshRenderer meshRenderer = combine.AddComponent<MeshRenderer>();
    meshRenderer.materials = materials.ToArray();
}

合并后的MeshRenderer只需要保留一个材质球:

再看一下Stats面板中的信息可以发现Batches指数已经由92变为42: