前言:
写这篇博客主要是为了让自己重新思考些东西。
Unity项目性能优化中,DrawCall 一直出现在我们的视野。而Drawcall 的减少,则跟 UI,场景,模型,息息相关。今天主要聊聊在场景或模型上合并材质减少DC的实现方法。
UI的DC优化有空再出。
为什么要进行材质合并?
假设在场景中有100个物体,使用的是相同的材质,排除Unity静态合并的影响下,渲染时DrawCall的数量就是100,而Drawcall的增加直接加重了设备CPU的负担。
那么怎样能减少DrawCall呢?
既然这100个物体使用的是相同的材质,那么就让他们合体呗,反正都是一家人,这样我们就有可能将这100个Drawcall变成1.
材质合并需要做什么?
合并材质,实际上是生成一个新的渲染器 和 一个新的网格,将多个子物体网格合并成新的网格,使用公共shader生成新的材质,并将小物体纹理合并成一张大的纹理,赋值为新渲染器的主纹理。
普通的MeshRender的材质球合并:
1.合并所有材质球所携带的贴图,新建一个材质球,并把合并好的贴图赋予新的材质球。
2.记录下每个被合并的贴图所处于新贴图的Rect,用一个Rect[]数组存下来。
3.合并网格,并把需要合并的各个网格的uv,根据第2步得到的Rect[]刷一遍。
4.把新的材质球赋予合并好的网格,此时就只占有1个drawcall了。
- void CombineMesh()
- {
- //获取所有子物体的网格
- MeshFilter[] mfChildren = GetComponentsInChildren<MeshFilter>();
- CombineInstance[] combine = new CombineInstance[mfChildren.Length];
- //获取所有子物体的渲染器和材质
- MeshRenderer[] mrChildren = GetComponentsInChildren<MeshRenderer>();
- Material[] materials = new Material[mrChildren.Length];
- //生成新的渲染器和网格组件
- MeshRenderer mrSelf = gameObject.AddComponent<MeshRenderer>();
- MeshFilter mfSelf = gameObject.AddComponent<MeshFilter>();