Draw call就是cpu对图形绘制接口的调用,CPU通过调用图形库(directx/opengl)接口,命令GPU进行渲染操作。
每一次绘制CPU都要调用DrawCall,调用DrawCall之前,CPU要进行很多准备工作:检测渲染状态,提交渲染所需要的数据,提交渲染所需要的结果,当DrawCall过多CPU会有很多额外的开销用于准备工作,CPU负载,GPU限制。
解决方案:把小的DrawCall合并为一个大的DrawCall中,这就是批处理思想。
使用批处理的注意事项:
合并的网格会在一次渲染任务中进行绘制,他们的渲染数据,渲染状态和shader都是一样的,因此合并的条件至少是:同材质、同贴图、同shader。最好网格顶点格式也一致。
尽量避免使用大量小的网格,当确实需要时,考虑是否要合并。
避免使用过多的材质,尽量共享材质。
网格合并的顶点数量有上限(Unity中好像是65535)
合并本身有消耗,因此尽量在编辑器下进行合并
确实需要在运行时合并的,将静态的物体和动态的物体分开合并:静态的合并一次就可以,动态的只要有物体发生变换就要重新合并。
参考:https://zhuanlan.zhihu.com/p/26386905
在unity菜单栏window-profiler可以看项目性能数据:
优化标准:
Mesh
动态模型:面片数材质数<3
骨骼数<50
静态模型:定点数<500
长时间音乐(背景音乐)压缩格式mp3
短时间音乐(音效)非压缩格式wav(例如战斗音效,如果压缩,攻击一次就需要压缩一次)
贴图长宽<1025
Shader
减少复杂数学运算
减少discard操作
一贴图优化:
二模型优化:
减少顶点数量
三减少冗余资源和重复资源:
1.Resources目录下不管资源是否被使用都会被打包
2.不同目录下的相同资源文件,如果被引用,那么大宝都会打包进资源包
3.保证同一个资源文件在项目中只存放在一个目录位置
具体细节设置在Edit-projectsetting-QualitySetting
二 遮挡剔除在摄像机视野范围内的渲染显示,不在范围内的不渲染显示
1. 全选要进行遮挡剔除的物体
2. 在static里面选中OcclusionCulling Static属性
3. 在Window-Occlusion Culling中设置烘焙,选择目标摄像机
把环境的光照效果提前计算好,生成一张光照贴图,这样以后就不需要再去实时渲染环境的光照效果
1.选择环境,再static里面选择lightmap Static
2.在window-Lightting-setting设置烘焙
3.在资源文件夹中会生成光照贴图信息,彩色的一个属性图标
把多个物体合并成为一个大的物体,需要通过代码实现,把要合并的物体放到一个物体下面作为子物体:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeshCombiner : MonoBehaviour {
// Use this for initialization
void Start () {
MeshCombine();
}
void MeshCombine()
{
MeshFilter[] filters = GetComponentsInChildren();
CombineInstance[] combiners = new CombineInstance[filters.Length];
for(int i = 0; i < filters.Length; i++)
{
combiners[i].mesh = filters[i].sharedMesh;
combiners[i].transform = filters[i].transform.localToWorldMatrix;
}
Mesh finalMesh = new Mesh();
finalMesh.CombineMeshes(combiners);
GetComponent().sharedMesh = finalMesh;
}
1.尽量不要动态的instantiate和destroy object,使用object pool
2.尽量不要再update函数中做复杂计算,如有需要,可以隔N帧(FixedUpdate)计算一次
3.不要动态的产生字符串,如Debug.Log("boo" + "hoo"),尽量预先创建好这些字符串资源
4.cache一些东西,在update里面尽量避免search,如GameObject.FindWithTag("")、GetComponent这样的调用,可以在start中预先存起来
5.尽量减少函数调用栈,用x = (x > 0 ? x : -x);代替x = Mathf.Abs(x)
参考博客:http://blog.csdn.net/leonwei/article/details/18042603
三 其他优化博文
http://www.cnblogs.com/harlan1009/p/3970584.html
http://www.cnblogs.com/chwen/p/4396515.html