在某些移动端项目中,对于DrawCall的要求是很严格的,我们一般查看DrawCall可以通过Statistics里面的Batches进行查看,一般对于移动设备的Batches要控制在200左右比较合适,所以降低Batches是很重要的。
我们常常会遇到一个物体下挂载很多很多个子物体,子物体的模型又比较精细,且都是静态的Mesh,这样就会造成大量的DrawCall,我们多次渲染一个小Mesh和一次渲染一个大Mesh之间需要取得平衡,保持帧率稳定在目标数字,这时候我们可以考虑使用合并Mesh,就比如下图中
这里面有非常多的面,在我们不进行处理的时候,可以看到我们的帧率和Mesh
基本稳定在100左右,且Batch在800左右,消耗了很多的DrawCall,所以我们一次性处理一个大的Mesh,减少DrawCall,而不是一次处理一个小的mesh,为了合并Mesh,对于相同的一些物体,
我们可以通过代码直接进行合并,代码如下:
using UnityEngine;
public class MeshCombine : MonoBehaviour
{
private void Start()
{
CombineMeshs();
}
void CombineMeshs()
{
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combines = new CombineInstance[meshFilters.Length];
for (int i = 0; i < meshFilters.Length; i++)
{
combines[i].mesh = meshFilters[i].sharedMesh;
combines[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);//关闭原始对象
}
MeshFilter parentFilter = gameObject.AddComponent<MeshFilter>();
parentFilter.mesh = new Mesh();
parentFilter.mesh.CombineMeshes(combines);
MeshRenderer parentRender = gameObject.AddComponent<MeshRenderer>();
parentRender.material = meshFilters[0].GetComponent<MeshRenderer>().sharedMaterial;
gameObject.SetActive(true);
}
}
开箱即用,挂载到父物体身上,就可以了,这里我们就用到了Combine这个方法,我们就是通过两个数组,一个数组把子物体的MeshFilter组件存储起来,然后创建一个和子物体长度相同的CombineInstace数组,把组件的mesh传递给它,最后在父物体身上创建meshFilter组件,就可以了
但是其实现在有很多Mesh合并的工具,比如这个叫Simple LOD的,下载地址如下:
文件 (lanzout.com)
导入后选中父物体,选择Tools中的SimpleLod
选择Merge child meshes即可!