造成性能瓶颈的原因主要以下几个方面:
(1)CPU
过多的DrawCall
复杂的脚本逻辑或者物理模拟
(2)GPU
顶点处理:过多的顶点、过多的逐顶点计算
片元处理:过多的片元(过高的分辨率,或者由于OverDraw造成)、过多的逐片元处理
(3)带宽
使用了尺寸很大且未压缩的纹理
分辨率过高的帧缓存
解决以上问题的途径:
(1)针对 减少DrawCall处理:
i:动态批处理-每一帧把可以进行批处理的模型网格(使用同一个材质)进行合并,再把合并后的模型数据传递给GPU。
优点:经过批处理的物体仍然可以移动,因为处理每帧时都会重新合并一次网格
缺点:要求严格,顶点属性规模要小于900;使用LightMap需要保证指向纹理中相同的位置;多Pass的Shader会中断批处理
ii)静态批处理-将需要进行合并的模型合并到一个新的网格结构中,这意味着这些模型不可以在运行时刻被移动
优点:高效,仅需要一次合并处理
缺点:在Drawcall中未合并前,共享Mesh对的网格可以共享数据,但是合批后,每一个物体会变成对应的一个该网格的复制品,往往需要占用更多的内存。
iii)共享材质-以上批处理在处理时都需要相同的材质。但是如果仅贴图不一样,我们可以合并纹理到图集Atlas。这样保证使用同一个材质,仅UV坐标发生变化。
建议:
1.尽量渲染静态批处理,同时注意小心内存的消耗 2.对于包含动画的这类物体,无法使用静态批处理,可以将不动的部分标记成Static
(2)
针对减少需要处理的顶点数目的处理:
i:优化几何体
ii:模型的Lod技术
iii:遮挡剔除技术
针对减少需要处理的片元数目处理
i:控制绘制顺序 在Unity中 那些渲染数目小于2500(如Background Geometry AlphaTest)的对象都被认为是不透明的物体,一般都是从前往后进行的,而透明队列则是从后往前。尽量减少使用半透明队列,从而减少overdraw。
ii:警惕透明物体;减少透明物体的面积,使用不同的相机来渲染GUI以及场景-从而避免GUI对场景的overdraw。
iii:减少实时光照和阴影
(3)
针对带宽节省的处理
i:减少纹理的大小,Mipmapping 多级渐远纹理技术 以及纹理压缩
ii:利用分辨率进行缩放