Unity性能优化之DrawCall
对U3D的一些资源优化
Unity性能优化之DrawCall
做U3D项目丰富的人都知道,优化的好坏一直是一个项目的评判标准之一,它直接影响到互动的体验。
(一)Draw Call的数量是决定性能比较重要的指标
Draw Call是导致性能下降的主要原因,CPU传送数据给GPU比较慢,GPU完成绘制后等待时间久。比如卡顿,掉帧,加载过慢,甚至卡死等原因。
引擎从摄像机可以看到的任何物体,这些物体的顶点(包括本地位置、法线、UV等),索引(顶点如何组成三角形),变换(就是物体的位置、旋转、缩放、以及摄像机位置等),相关光源,纹理,渲染方式(由材质/Shader决定)等数据都会影响Draw Call的数量。如果要优化Draw Call,就要减少它的个数,而优化Draw Call的方法有很多种,比如从美术资源方面优化Draw Call,或从U3D引擎中优化Draw Call。插件中优化,shader中优化,代码中优化等。但这些优化方式都是会相互影响。美术无脑优化Draw Call,而不了解程序是否可以使用。程序优化Draw Call,而不管这些美术资源是否可行。导致各干各的,各自优化各自的,也不管是否真的优化成功了,只是按部就班的优化,不仅无效,还会影响性能。
Unity中如何看到Draw Call的数量,目前Unity的Draw Call是Batches.如图下:

(二)Draw Call关于U3D引擎中的优化方式:静态批处理
静态批处理方式,只要场景中的物体是不移动的,比如建筑,山等,可以选择为Static静态,这种方式可以减少Draw Call。只要这个物体不移动,并且拥有相同的材质,静态批处理就允许引擎对任意大小的物体进行批处理来降低描绘调用,只要这个物体确认不移动,不旋转和缩放,你就可以在Inspector中将Static复选框打钩,如图下:

如果有动态的物体请不要勾选,比如移动的角色,奔跑的汽车,如果加入了动画,再勾选Static,动画就会失效,还有请把自动烘焙关掉,因为烘焙会烘静态物体,如图下:

举个例子:新建4个不同的物体,他们的模型结构不同,但是他们使用的相同的材质球,,如果他们不勾选Static,Draw Call的个数是4,如图下:

如果我们将这4个物体的Static勾选为静态,它的Draw Call的个数变为了1,如图下:

所以在模型制作的时候,材质尽量都公用,比如金属的材质就全部指认为一种金属材质,木头的就全公用一个木纹贴图,这样勾选Static才有效果。否则不会有任何的优化。因此美术制作时,材质越少,Draw Call越少,这就需要美术来进行材质贴图合并,模型公用相同的材质,后面我会深入讲解模型与材质的优化。
(三)Draw Call关于U3D引擎中的优化方式:动态批处理
U3D的Draw Call动态批处理机制是引擎自动进行的,无需像静态批处理那样手动设置Static.无需勾选。
首先模型我们需要做成预制体Prefab,然后动态实例化出来,前提是动态物体共享相同的材质球,则引擎会自动对Draw Call进行优化。也就是使用批处理。
做个测试,把一个cube做成Prefab,然后实例化出来500个,看下Draw Call的数量,如图下:

可以看到Draw Call的数量为1,500个mesh,Draw Call才1,而我们除了实例化,什么也没做,这就是U3D引擎为我们自动处理了。
但是动态处理有时候无效果,那是因为U3D有一些约束的规则:
(1)批处理动态物体需要在每个顶点上进行一定的开销,所以动态批处理仅支持小于900顶点的网格物体。
(2)如果你的着色器使用顶点位置,法线和UV值三种属性,那么你只能批处理300顶点以下的物体;如果你的着色器需要使用顶点位置,法线,UV0,UV1和切向量,那你只能批处理180顶点以下的物体。
(3)不要使用缩放。分别拥有缩放大小(1,1,1) 和(2,2,2)的两个物体将不会进行批处理。
(4)统一缩放的物体不会与非统一缩放的物体进行批处理。
(5)使用缩放尺度(1,1,1) 和 (1,2,1)的两个物体将不会进行批处理,但是使用缩放尺度(1,2,1) 和(1,3,1)的两个物体将可以进行批处理。
(6)使用不同材质的实例化物体(instance)将会导致批处理失败。
(7)拥有lightmap的物体含有额外(隐藏)的材质属性,比如:lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行批处理(除非他们指向lightmap的同一部分)。
(8)多通道的shader会妨碍批处理操作。比如,几乎unity中所有的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道。
(9)预设体的实例会自动地使用相同的网格模型和材质。
所以,尽量使用静态的批处理。
动态批处理,需要在unity中开启,会导致CPU消耗,如果不是GPU有瓶颈,最好关闭动态批处理。
OtherSettings中,如图下:

static batching 静态批处理
dynamic batching 动态批处理
