Mesh网格合并通常是优化中常用的小手段,目的是为了减少drawcall,大量的drawcall会造成CPU的性能瓶颈。例如下图中船只里的钢材货物,由诸多钢材模型堆砌而成。
我们将其放在一个空场景里查看Stats信息,可见Batches指数为94
下面我们进行网格合并,将所有的钢材合并为一个Mesh,代码如下:
代码语言:javascript复制//绘制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: