目录
前言
一、优化目标
二、优化过程
1.确定性能目标
2.确定观测指标
3.具体实践
1.处理阴影
2.场景内物体的渲染
3.光照效果
总结
前言
笔者只是一大三实习生,对于unity的性能优化掌握并不深刻,我在本案例中采取的优化方案也比较简单狭隘,本篇博客用于记录此次优化实验,对于本文出现的错误之处还恳请指正。
源项目(非URP):https://pan.baidu.com/s/1kalTdPD8WRqicrOeQy613g
提取码:ves2
一、优化目标
总的来说,性能优化的终极目标是保证游戏的流畅运行,避免卡顿、显示异常的发生。
本项目主要用于VR游戏场景应用,最终将导入到VR设备上运行。
由于VR设备直接通过VR头盔将画面投射到玩家眼部前方,玩家游戏体验更逼真但同时也对视觉伪影更敏感。相较于传统PC,VR 游戏通常需要更高的刷新率来使游戏的沉浸感更强。
本项目主要是一个室内场景
在未优化之前,直接将本项目导入到VR设备中,FPS只有30左右
一般而言,FPS>=60才是可以接受的情况
如果去掉所有的光,则此时FPS稳定在72上下,在性能上达到了优化目标。
我们的优化目标就是在尽可能不破坏原场景的前提下,让FPS又可以接受。
二、优化过程
1.确定性能目标
本项目的性能目标是优化后其FPS值(VR设备上运行)能够稳定在60以上。
由于在进行优化任务时,我手边并没有可用的VR设备,故对项目直接运行、关闭光源运行时的各项数值进行监测记录,并用以指导后续优化。
2.确定观测指标
我们主要通过Unity Statistics窗口 和 frame debugger来对性能进行监控,主要观测指标有
FPS值、Batches、Tris、verts、SetPass calls 和 Shadow caster
3.具体实践
首先,我们导入项目后关闭所有的light,直接运行游戏并记录各项指标
可以看到FPS在470-500左右,tris 和 verts 也差不多在130k 和 110k,
我们以此时stats面板中的数据作为优化的最终目标
重新打开光源,复原项目,运行并查看各项观测指标。
此时,FPS大致在110上下浮动,Tris和Verts的数量很大,Batch数值同样高
saved by Batch为0,很明显此场景并没有进行合批
Shadow Caster有1k之多,阴影开销很大。
由于本项只有一个摄像机控制脚本,故不考虑优化玩家脚本的方向。
为了详细查看渲染情况,我们打开Frame debugger,捕获当前帧并查看数据:
可以看到在drawing中,对shadow阴影的处理开销占比巨大(719/1034)
我们首先尝试优化光照所产生的阴影。
1.处理阴影
尝试在light组件中直接关闭阴影生成
可以看到FPS有巨大提升,且shadow caster指标为0 了。
但是画面也过于明亮,且由于失去了阴影,看起来也不自然
直接关闭阴影生成不可行,撤销。
注意到场景是一个室内场景,外部只是做一个房间窗口的背景板,外部的terrain很大,但是上面几乎没什么东西。
对于比较平坦的外部terrain,没有投射阴影的必要。在大部分情况下它更多的是接受其他物体的投影,而非自投影。
关闭terrain的shadow caster
关闭前:
关闭后:
关闭后可以看到虽然 shadow caster指标下降了200左右,但是Fps只提升了一点,优化效果不是很明显。
再看场景内部,周围环境中其实有许多小物件
比如桌上的刀叉、书本之类的。
大部分小物体因为体积较小,也没有产生阴影的必要,因此将部分微小物体的阴影生成也关闭。
(注意只是“部分”关闭,有的小物体阴影是有留存必要的,比如桌上的苹果)
但是处理后的效果还是和之前的差不多,各项指标也没有太大变化,由于小物体的数量并不是很多,所以性能的提升不是很明显。
对于物体的阴影调节差不多结束了,我们直接去Project setting中对shadow的生成品质进行调整
将阴影调低后性能有一些提升了,此时FPS稳定在125左右浮动。
为了确保无误,再次使用frame debugger进行查看,可知阴影的开销相较之前确实有被优化。
2.场景内物体的渲染
现在继续优化场景内物体的渲染情况
可以看到场景内有很多相同的物体(大部分都是同个静态物体的拷贝)且均为静态,因此可以采用static batching的方式来进行合批处理。
Unity已经集成了静态批处理的功能,只需要在project setting中勾选static batching即可。
再次运行,可以看到saved by batching指标确实增加了,static batching确实在发挥作用。
但是对于整个性能的提升微乎其微,可能是因为相同材质的物体个数太少,大部分物体的种类都不尽相同。
又由于这是一个室内的场景,玩家在游玩时就处在房间内部,和各个物体的距离很小,LOD分级细节处理似乎也不太适用,模型不太好从这个分级方向来优化。
不过我们还是可以通过降低场景中模型的精细度来进行优化。原理即是通过对精细的模型进行减面处理,保持物体原有的轮廓,删掉冗余面或是对形状只有微小影响的面,来达到优化渲染的目的。
例:
但是我不太会对模型进行减面相关的操作,人工修改模型精细度不是我所考虑的 =-=。。。
(PS:后来实习导师告诉我这方面确实有对应的自动化减面插件来处理,人工修改模型虽然效果好但是也很费人)
室内场景似乎对于遮挡剔除(occlusion culling)来说很合适,但是这个场景中房间外部基本上没啥其他的东西,就一个种了几棵草的terrain,没有什么东西好剔除的。还是试一下吧,进行一下occlusion culling bake看看效果。
果然没多大效果,各项指标还是和原来差不多的。
说到terrain,其实观察一下可以发现在一帧的drawing中对terrain的绘制也是一个很大的比重
在scene窗口也可以看到terrain的三角面很多很复杂
关于对terrain的优化,从网上有收集到一些信息:
一般通过地形mesh来对unity的terrain进行替代,根据terrain data 将mesh信息与混合后的地形纹理烘焙出来,并通过prefab生成地形块。
这个我也不太会。。。
那么似乎只能对这些细小模型的网格数据进行优化了,好在unity也集成了这个功能:
返回游戏,发现没什么卵用,还是和原来差不多的样子。
其实还可以通过挂脚本来对小物体进行网格合并,但是好像场景内这些聚集在一起的小物体个数太少了,使用起来也蛮麻烦的,故pass掉。
具体的实现代码可以在官方文档查看。
3.光照效果
emmmmm,现在那就只能对光照本身进行优化了,在本项目中,实时光的计算确实是一个非常非常巨大的开销。一般来说这样的场景都不会只挂realtime light,或多或少都会进行一些bake来优化渲染开销。
我们尝试将light模式改为Mixed 模式 和 Baked模式来看看效果。
在Mixed模式下,我选择的是Subtractive:
这种mixed类型会对静态物体进行完全烘焙,同时动态物体仍然能够在它们之上进行投影。开销相较于Baked indirect更低,不过新版本也许shadow mask会更好。
效果非常好,可以看到FPS值已经稳定在了230上下。
并且整个画面本身也非常的自然,光照效果甚至比实时光还要好一些,画面也不像实时光那样惨白。
可以看到这种模式下shadow caster仍然存在,但是数量已经大幅度降低了,
tris和verts数目也大幅度降低,渲染负担减少。
使用mixed模式的光照效果非常好。
那么继续看一下baked模式下表现如何,将场景内light属性设置为baked,为了加快烘焙计算,我选择了progressive GPU模式
看看结果:
baked模式下的画面光照效果非常的柔和,环境光也很自然,
对于游戏性能的提升也是肉眼可见。此模式下游戏的FPS已经稳定在了500左右,是原始fps的5倍。
Shadow caster直接变为了0,不存在阴影的渲染(所有都烘焙好了),verts和tris的数目也是原来的十分之一。可以说优化效果是极好的了。
此时stats各项数据都接近关闭所有光源运行时的数值,优化应该达到了目标,优化到此结束。
关于画面亮度的问题,可以看到baked烘焙模式将光线处理得更加自然了,没有原始的刺眼白光了。但是由于生成light map的原因,在空间上的开销也变大了。当然,这一部分也可以在light中设置烘焙各项参数,比如采样度、light map精细度等。
总结
本项目并不是一个URP项目,因此一些更加有效和细节的优化方式并没有提及。
主要的优化方向一般来讲就三个,CPU、GPU、内存。本项目因为没有挂什么脚本,因此思考的方向还是蛮简单的,主要就是从渲染的角度来进行操作。
项目中也没有挂载UI面板,因此这UI一部分的优化也省去了。
而且该场景也没有添加任何post processing,又简化了优化操作。
文中我所进行的优化操作其实也并不是很严谨,在优化过程中我并没有仔细去分析内存、空间的使用情况,因此所得的实验结果也存在一定问题。
关于Unity游戏进行性能的分析,我总结了大致流程如下:
①确定性能目标:确定游戏的性能目标(例如:帧率、分辨率、延迟、渲染速度)
②确定观测指标:确定好监视哪些参数以分析性能情况,通常的指标为帧率、GPU使用率、CPU使用率、Memory使用情况
③选择合适的性能监视器:常用的有unity自带的profiler、frame debugger等,可以实时检测游戏对于计算资源的使用情况
④收集、记录游戏测试运行中产生的数据,并通过debug结合数据分析问题所在
⑤优化代码、参数、游戏设置
⑥重复 4-5
⑦验证优化结果,将游戏在实机进行运行验证。