减少draw call
- 批处理是为了减少线帧的draw call最常用的技术了。 CPU需要检查哪些光源该物体,绑定Shader并设置它的参数再发给
- GPU,场景里东西很多的时候就很耗了。
- 处理1000个三角形比处理一个有1000 个三角形物体要大得多,在这种情况下GPU没啥变化,但CPU会跑不动了。
- 使用同一个材质的物体可以一起处理,因为物体顶点会被合并在一起。
- 动态批处理由Unity自动完成,我们什么都不用做,但会有一些限制。
- 静态批处理自由度高,限制少,就是不能再移动物体了,还会占用更多内存。
动态批处理:
物体用同一材质并满足一些条件,Unity就会自动批处理了。基原理是合并同一材质的网格传给进行GPU处理,每帧会合并一起,所以物体可以移动。
主要的限制条件:
- 顶点小于900,如再加上法线和纹理坐标则是不能超过300。以后会更多…
- 统一缩放,比如都是(1,1,1)、(1,2,3)等…
- 指向光照纹理的同一个位置。
- 多Pass的shader 会被中段批处理。
- 等…
静态批处理:
模型大小没限制,原理是会在运行之初就把要静态批处理的模型合并到一个新的网格中,因此不能再移动了。但它往往会占用更多的内存,如果使用了1000个同样的模型,就会多1000倍的内存。
共享材质
即便使用了相同的材质也可能参数需要有所不同,如果是纹理不同,我们可以合并到更大的纹理中可以理解为是一个图集。如果是参数不同,常用的方便是使用风格的顶点数据来存这些参数。
注意事项:
- 尽可能使用静态批处理,但要小心内存。
- 使用尽可能少的顶点和顶点属性。
- 动态物体可以把期静态部分调为Static。
减少顶点数目
顶点数目过多会造成GPU的负担,可以使用以下方法优化:
- 与美术沟通,减少三角形数量。
- LOD(Level of Detail)技术,离摄像机远的物体减少面片数量,使用LOD Group组件使用不同等级模型。
- 遮挡剔除,可以减少像素重绘。
减少片元数目
这部分重点在于减少overdraw重绘次数。
- 控制绘制顺序如Queue2500以下的。
- 尽量少使用半透明物体,因为需要混合重绘。
- 挡住屏幕大部份的物体可以先画,因为如果是不透明的,他后面就会被剔除。
- 而对于天空间通常放在后面渲染,如Geometry+1
- 减少实时光照和阴影。
减少带宽
减少纹理大小
- 图片使用2的整数次幕大小。
- 使用多级渐远在技术(图片类型改Advanced,勾选Generate Mip Maps)。
利用分辨率缩放
使用较小的分辨率
减少计算复杂度
计算复杂度同样会影响游戏的渲染性能。
Shader的LOD技术
SubShader{
Tags{"RenderType"="Opaque"}
LOD 200
只有Shader的 LODh于某个值,这个Shader才会被使用。
代码优化
在游戏中,对像数<顶点数<像素数,所以计算应该放在对象或逐顶点中。
- 尽可能使用底精度的运算。
- (float/hight)高精度适用一存顶点坐标等变量,我见过速度慢。
- (half/mediump)中精度适用于一些标题、纹理坐标等,速度是float的两倍。
- (fixed/lowp)底精度适用于存变更和归一化后的方向失量,速度是float的4倍。
- 避免对底精度用swizzle操作(如Color.xwxw)
- 纹理UV可以合并在一个变量中,如分别使得xy和zw分量
- 尽量不使用全屏的屏幕后处理效果
- 尽可能不要使用分支语句和循环
- 尽可能不要使用sin、tan、pow、log等复杂运算
- 尽量不要使用discard操作
更具体的说明可以参考《Unity Shader入门精要》冯乐乐的。