Unity简单项目优化案例(含源项目)

目录

前言

一、优化目标

二、优化过程

1.确定性能目标

2.确定观测指标

3.具体实践

1.处理阴影

2.场景内物体的渲染

3.光照效果

总结


前言

笔者只是一大三实习生,对于unity的性能优化掌握并不深刻,我在本案例中采取的优化方案也比较简单狭隘,本篇博客用于记录此次优化实验,对于本文出现的错误之处还恳请指正。

源项目(非URP):https://pan.baidu.com/s/1kalTdPD8WRqicrOeQy613g

提取码:ves2


一、优化目标

总的来说,性能优化的终极目标是保证游戏的流畅运行,避免卡顿、显示异常的发生

本项目主要用于VR游戏场景应用,最终将导入到VR设备上运行。

由于VR设备直接通过VR头盔将画面投射到玩家眼部前方,玩家游戏体验更逼真但同时也对视觉伪影更敏感。相较于传统PCVR 游戏通常需要更高的刷新率来使游戏的沉浸感更强。

本项目主要是一个室内场景

在未优化之前,直接将本项目导入到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自带的profilerframe debugger等,可以实时检测游戏对于计算资源的使用情况

④收集、记录游戏测试运行中产生的数据,并通过debug结合数据分析问题所在

⑤优化代码、参数、游戏设置

⑥重复 4-5

⑦验证优化结果,将游戏在实机进行运行验证。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值