您的位置:首页 > 移动开发 > Unity3D

Unity 性能优化 系列(一)基本概念

2016-08-23 12:49 375 查看
前言:

  对于Unity游戏在各种平台的优化打算出一系列内容(估计是个长期活),不过无论哪种优化除开一些较为特别的平台差异外,无非就是减少基本计算的复杂度,减少各种指令调用数量,减少数据传输量,好吧,先来个思维导图来描述一下基本的优化方法。



  根据此图,我们可以知道渲染优化所进行的三方面优化:

========================================================================== 

一:<CPU>

(1)DrawCall

  Unity每渲染一个带材质的模型就会调用一次DrawCall,CPU在每次通知GPU进行渲染之前,都需要提前准备好各种数据(如位置,法线,颜色,纹理坐标等),然后调用一系列API把它们放到GPU可以访问到的指定位置,然后会调用一个绘图指令,这个指令就是DrawCall了。

  而且每个DrawCall调用前都会改变很多渲染状态,这些操作非常耗时,过多的DrawCall会让CPU把大部分时间都花费在提交DrawCall上,导致瓶颈出现。

  减少DrawCall的方法主要就是批处理:

  *动态批处理:系统会自动将各个物体合拼成同一个物体,只调用一次DrawCall,并且单个模型仍然可以进行移动,但必须满足如下条件:1,使用相同材质。2,顶点属性低于900。3,假如存在光照纹理必须保证所有物体指向光照纹理的同一位置。4,材质Shader在多个关照的情况下中不能有多个PASS。

  (顶点属性:假设顶点有300,而其属性有顶点,法线,纹理坐标三种,即顶点属性为900,此数据可能在以后会改变)

  *静态批处理:方法很简单,只需要把模型的Static勾选上,这个无论物体拥有的材质是否相同也可以提高效率,不同的材质合并虽然仍需要调用多个DrawCall,但可以减少这些DrawCall之间的状态切换,提高效率。

  (注意,假如使用N个静态合拼的物体都共享了同一个网格,那么合并时将会产生N-1个拷贝,内存将会增大N-1倍,注意,假如当有处理其他光照的Pass在时这些PASS不会被静态处理,此时只会处理平衡光的BasePass部分)

  *基于批处理的共享材质:为了更好的应用批处理,如果同一种材质只有纹理不同,我们可以合并纹理然后重新赋值UV,假如材质微小参数不一样的话,该材质将不会相同,批处理也不会成功,但是我们可以使用顶点颜色来对每个物体进行调整。注意,访问共享材质使用Renderer.sharedMaterial,假如使用Renderer.material来修改材质,Unity将会创建一个该材质的复制品,破坏批处理。

  *额外注意:批处理需要把多个模型变换到世界空间再合并它们,但是Shader中存在一些基于模型空间下坐标的运算,那么往往会得到错误的结果,这时需要使用DisableBatching。而且对于使用半透明材质的物体通常需要严格的从后往前绘制,对于这些物体Unity会首先保证绘制顺序,再尝试批处理。

  第二,保证合拼物体的网格数据结构统一性,也就是说假如100个物体,其中有99个物体仅含有Vertex、UV等数据,而其中一个含有Vertex、UV、Normal等数据,那么和平后的所有模型都会自动增加额外的Normal数据。

(2)复杂算法

  这个范围太广了,查找算法,AI,路径搜索,布娃娃,动作混合一大堆,这个不同的游戏有不同的功能需要,所以这个留待具体问题具体分析。

(3)资源加载

  关于资源加载因为涉及到AssetBundle的大幅故事,所以在此不作详细解析,将于后续进行更详尽的讨论。

(4)GC优化

  GC(Garbage Collector)就是C#里面的垃圾回收机制,自动回收不再使用的内存,不过在移动平台上这就是一个大问题,当垃圾回收时会导致CPU负荷过大,因此我们需要降低垃圾出现的概率:具体做法:

  1.不要使用字符串连接,因为会出现大量残余垃圾。

  2.使用“for”代替“foreach”,”foreach”每次迭代产生24额外字节。

  3.用“if (go.CompareTag (“Enemy”)”来代替“if (go.tag == “Enemy”)”,在一个内部循环调用对象分配的标    签属性以及拷贝额外内存,这是一个非常糟糕的做法。

  4.使用对象池。

  5.不使用LINQ命令,因为它们一般会分配中间缓器,而这很容易生成垃圾内存。

(5)视区外区域功能屏蔽

  1.使用细节层次的定制关卡将远处的敌人AI关闭。

  2.移动平台和障碍,当它们远去时其物理碰撞机也会关闭。

  3.Unity内置的“动画挑选”系统可以用来关闭未被渲染对象的动画。

  4.所有关卡内的粒子系统也可以使用同样的禁用机制。  

========================================================================== 

二:<GPU>

  其实说到GPU主要就是三个东西,一个就是逐顶点处理,一个就是逐片元处理,还有一个就是基于屏幕图像的后期处理(其实也是顶点处理和片元处理)。

(1)顶点处理

  减少顶点这个就比较容易了解了,减少顶点既可以减少骨骼模型运算时的次数,也可以减少传输给GPU的顶点数量,还可以减少逐顶点计算时的顶点数,减少顶点实在是太划算了,不仅提高CPU计算效能,也提高了GPU计算效能。

  减少顶点的方法包括:

  *优化几何体,主要是制作模型时尽量移除不必要的硬边和纹理衔接,可以避免边界平滑和纹理分离,从而避免产生顶点分离,减少顶点数量。

  *LOD(Level of Detail),即远离摄像机时,减少模型上面片数量,提高性能。组件为LOD Group。

  *遮挡剔除(Occlusion culling),原理是使用一个虚拟的摄像机构建一个潜在可见层级结构,在运行时刻摄像机使用这个数据来识别物体的可见性,既可以减少处理的顶点数目,也能减少DrawCall。

(2)片元处理

  首先片元处理的优化方法是要减少OverDraw(即同一像素被重绘制多次),减少OverDraw的方法主要包括:

  *控制绘制顺序,对于不透明的物体,我们采取从前到后对物体进行渲染排序,这样可以有效减少OverDraw。例如天空盒因为其通常属于最后绘制的,可以将他的队列设置为所有不透明物体之后。

  *要注意透明的物体,因为半透明要得到正确的渲染效果,则必须从后往前渲染,因此透明物体几乎一定会造成OverDraw,因此要时刻主要半透明物体的数量。

  *减少实时光照和阴影,当一个场景中包含N个逐像素的点光源,而且使用了包含逐像素的Pass的shader,那么DrawCall数目也提高N倍(CPU瓶颈),同时也增加了OverDraw(GPU瓶颈),这是因为对于逐像素的光源来说,被这些光源照亮的物体需要再被渲染一次。减少光源的方法包括:烘焙出LightMap(静态),或者使用lookup texture(动态光照查找表)。

  此外,动态阴影也是一个非常消耗性能的效果,我们应该尽量减少实时阴影,使用烘焙吧静态物体的阴影信息储存在光照纹理中,只对环境中一部分主要物体作适当的实时阴影。

(3)减少计算复杂度

  *Shader LOD,在Shader中可以设置“LOD 200”,就是当Shader的LOD值小于某个设定的值,该Shader才会被使用,其他LOD值大于此值的Shader都不会被渲染。

  *代码优化,代码优化的效率通常是”对象数<顶点数<像素数”,规则是尽量使用低精度的浮点数计算,这样可以提高计算速度(例:fixed/lowp的计算速度大约是float的四倍),所以请注意精度的选取。

========================================================================== 

三:<内存带宽>

  *MipMap,长宽值最好是2的整数幂次方,开启后会生成很多不同大小的小纹理,在游戏过程中可以根据距离物体的远近动态选择哪一个纹理

  *分辨率优化,即进行分辨率缩放。

  *多平台优势格式:

  android:ETC1(不支持透明),可以使用额外的Alpha通道信息的Alpha8格式纹理。

  IOS:PVRTC

======================
9ca6
==================================================== 

总结:以上提到的优化方式仅为概括性渲染优化方法,更多实质的干货(包含调试方法及数据分析等)将会陆续更新(虽然并不知道更新具体时间)。


主要参考:

Unity Shader入门精要 – 冯乐乐(以下亚马逊连接)

https://www.amazon.cn/Unity-Shader%E5%85%A5%E9%97%A8%E7%B2%BE%E8%A6%81-%E5%86%AF%E4%B9%90%E4%B9%90/dp/B01G95GMU6/ref=sr_1_1?ie=UTF8&qid=1471970961&sr=8-1&keywords=Unity+Shader%E5%85%A5%E9%97%A8%E7%B2%BE%E8%A6%81

总结使用Unity 3D优化游戏运行性能的经验

http://gamerboom.com/archives/76214

Unity 的一些优化总结

http://www.jianshu.com/p/3acee1101fe4

声明:

该文仅作学习与记录之用,欢迎技术纠错和讨论;

非技术性言论皆为一家之谈,如有不同意见请坚持己见;

如有雷同可能为学习汝之所得,请各位巨人的肩膀还请继续空出位置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity 性能优化 游戏