Unity优化相关

这里介绍关于Unity优化的简单知识点,主要涉及大小优化和性能优化两个方面, 包括通用优化技术知识点 各平台专用优化技术知识点和优化相关工具知识点 后续会不断更新

通用优化技术知识点

Mono虚拟机的弱点

Unity早期采用mono虚拟机技术来达到一次开发多平台部署运行的目的,这样一般会把mono虚拟机放到打包出来的程序中,无疑增大了包的大小,后来Unity引用IL2CPP技术来解决此短板,IL2CPP打包出来的程序具有更加小的程序容量和更快的运行速度(因为将程序代码转成了c++)在playersettings里面有相关的选择选项选择使用哪种
在这里插入图片描述
官网也对这个选项有一些讲解
Standalone Player settings
在这里插入图片描述

Drawcall数量控制

通常的游戏中,Drawcall数量是最需要控制的一个性能优化点,Drawcall是由CPU负责计算生成再放置在渲染缓冲区的渲染指令,GPU从渲染缓冲区取得指令后进行渲染执行,因为GPU的并行渲染机制使得GPU对于Drawcall的渲染完成是相当快的,DrawCall数量太多往往导致程序卡在CPU的计算生成这个方面,而这时的GPU一般都是没事可干,在渲染缓冲区干等CPU传达的Drawcall。移动一千个总大小为1M的文件和移动一个大小为1M的文件,往往是前者占用的时间多很多,因为前者对单个移动命令要做的准备工作做了1000次而后者只做了一次,CPU卡的原理就类似于这个,如果我们需要渲染一千个三角形,那么把它们按一千个单独的网格进行渲染所花费的时间要远大于直接渲染一个包含了一千个三角形的网格
所以一般的思路就是尽量减少drawcall的数量,一般有动态批处理和静态批处理,官方文档在这里Draw call batching

动态批处理,Unity会把符合条件的使用材质完全相同(包括数量)并且没有勾选Batching Static的物体拉去做动态批处理,动态批处理会消耗一定的CPU计算在这里插入图片描述
进行动批物体符合的条件是:

  • 单个物体的MeshRenderer里面的mesh顶点属性要小于900。如果你的着色器使用顶点位置,法线和UV值三种属性,那么你只能批处理300顶点以下的物体;如果你的着色器需要使用顶点位置,法线,UV0,UV1和切向量,那你只能批处理180顶点以下的物体。因此,优化策略就是shader的优化,少使用顶点属性,或者模型顶点数要尽可能少。
  • 这些使用相同材质的物体,他们的材质里面用的shader代码里面,不能有多个Pass,多Pass的shader会中断批处理。比如,几乎unity中所有的内置着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道,这就会要求额外的渲染次数,所以绘制 “额外的每像素灯”时不会被批处理。
  • 关于这些相同材质的物体因为的transform的scale不同而不能动态合批这个限制在unity5版本已经没有了
  • 拥有光照贴图的物体有关于光照贴图的参数,例如光照贴图索引或光照贴图的偏移与缩放的时候,动态光照贴图的游戏对象应该指向完全相同的光照贴图的位置,这意味着这些使用相同材质的物体,这个相同材质上的关于光照贴图的参数要完全一致

静态批处理:Unity会把符合条件的使用材质完全相同(包括数量)并且勾选了Batching Static的物体拉去做静态批处理,静态批处理只需要这两个条件,一般把游戏中永远不会移动、旋转和缩放的物体勾选Batching Static选项,会动的物体勾选了可能会导致不理想的情况, 只要在PlayerSettings里面勾选了开启静态批处理,则要做的就只是把需要的物体勾选BatchingStatic,因为静态批处理是Unity自动进行的,经过动态批处理后,相同材质的物体只占一个drawcall,对于顶点属性太多的物体(>900),可以使用静态批处理来减少DC.
静态批处理通过内存来换取速度,如果在静态批处理前有一些物体共享了相同的网格(例如两个相同的箱子),那么每一个物体都会有一个该网格的复制品,即一个网格会变成多个网格被发送给GPU。如果这类使用同一网格的对象很多,那么这就是一个问题了,这种时候我们可能需要避免使用静态批处理。
如果场景自带静态物体,会合并批次。如果静态物体是程序中通过代码加载进去,例如场景加载后再读取预制体动态加载进去的,就不会自动合并批次,需要你加载完后调一下手动合并批次的接口,StaticBatchingUtility.Combine 合并。

在PlayerSettings里面有关于是否开启动态批处理和静态批处理的选项,各个平台都有这个选项,一般勾选了这个选项,有符合规则的物体,动态合批和静态合批unity都会自动进行
在这里插入图片描述

Unity中内建的批处理机制所达到的效果要明显强于使用几何建模工具如3dMax的批处理效果,因为,Unity引擎的批处理操作是在物体的可视裁剪操作之后进行的,处理的几何信息少很多。
如果你的两个材质仅仅是纹理不同,那么你可通过纹理拼合来将这两张纹理拼合成一张大的纹理,这样,你就可以使用这个单一材质来替代之前的两个材质了。
如果你要通过脚本来访问复用材质属性,要注意:改变Renderer.material将会造成一份材质的拷贝,这意味着这个物体从合批中分离开来了, 因此,你应该使用Renderer.sharedMaterial来保证材质的共享状态。
DrawCall的数量与画面的总的Pass数量成正比,

实时光的使用以及阴影效果

同样的设置,但是如果你将灯光的阴影效果打开,你会发现DrawCall大幅增加,所以一般可以使用lightmap即光照贴图来代替一些实时阴影

发布了89 篇原创文章 · 获赞 14 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43149049/article/details/104455271