搜索 Unity

怎样在摄像机上优化游戏性能:第一部分

2021年9月23日 类别 游戏 | 8 分 阅读
Accelerate Success Logo
Accelerate Success Logo
涵盖的主题
分享

Is this article helpful for you?

Thank you for your feedback!

世界会因创作者更多而更美好。为了帮助广大创作者进行创作,Unity的Accelerate Solutiions Games团队将在新的Accelerate Success系列中介绍团队日常工作中总结出的技术经验。该团队是Unity的一支专业技术服务团队,可为客户提供咨询、开发合作和开发全包等服务。在那些最希望推动引擎到极限的客户下面,他们经常承担一些最复杂、最具挑战性的Unity工作。

本系列由电子书和网络教学两部分组成,我们希望藉此来回馈那些影响或塑造了Unity的游戏业群体。在与全球各大游戏工作室的合作中,我们总结了一系列的使用技巧、方法及最佳实践,现在在Accelerate Success系列中悉数分享。Accelerate Success的每篇博文都将由一位Accelerate Solutions团队的软件开发顾问编辑并撰写,内容都将以现实中的情形和发现为基础。 

本文则由Accelerate Solutions Games团队的负责人之一Bertrand Guay-Paquet编写。Bertrand就职于Unity的斯德哥尔摩办公室,本文中的结论总结自于他本人的Project Reviews(项目审查)工作。 

什么是Project Reviews?

Accelerate Solutions Games团队的软件开发顾问们主要负责的工作就是Project Reviews。订阅了Unity Integrated Success套餐的Unity客户每年都有一次委托Unity专业顾问检查项目的机会。在此期间,我们会花两天时间赶往现场(或在Zoom上)仔细审查客户的项目。软件开发顾问们将深入研究项目或工作流程,并提供一份全面的报告,指出项目在速度、稳定性和效率上可以优化的部分。 

而在实际工作中,我们经常会看到很多项目会带有多余的摄像机。这类问题一般会被立即调查,而对应的解决方案通常离不开摄像机的合并或删除。

Profiler capture with multiple Cameras - A red flag!
Profiler里的多个摄像机是优化关注点。

多年来我们发现,有许多市面上的游戏会被过多的摄像机拖累性能。而迄今为止,开发者们还没有为场景的各种摄像机配置建立一种标准。为了帮助读者深入了解该问题,本书将讨论如何在移动硬件上为摄像机性能开展基准测试。我们将在Unity的内置渲染管线和通用渲染管线上开展测试。

怎样在摄像机上优化游戏性能:第一节

摄像机究竟是干嘛的?

从基本定义来说,摄像机确定了其在场景中的视角、位置和方向,这三个参数决定了镜头的内容(渲染器)。被渲染出的图像将经由摄像机输出到显示器或RenderTexture中,这时,摄像机的矩形视窗所覆盖的区域便是输出。

在上层的Unity引擎代码中,每个激活的摄像机在每帧上必须:

  • 搜集所有视野中可见的渲染对象。反过来说就是所谓的剔除(Culling),剔除那些不可见的对象,只留下构成输出图像的渲染对象,交由GPU绘制。即通过尽量减少渲染对象来提高性能。这一过程有三个子流程组成:
    • 由摄像机剔除遮罩来排除层级上不匹配的渲染对象。
    • 由视锥剔除(Frustum Culling)排除那些视锥(即观察范围)之外的渲染对象。
    • 由遮蔽剔除(Occlusion Culling)排除那些被不透明物体遮挡住的渲染对象。这一步骤通常作用有限,并非必需。
  • 确定渲染对象的绘制顺序。总的来说,透明物体的绘制顺序为从后往前,不透明物体大致为从前往后。渲染顺序也受材质或着色器的Render Queue(渲染队列)、排序层和排序先后影响。
  • 为每个渲染对象生成绘制命令,将任务传给GPU。这些命令定义了用于渲染的材质和网格。

可以想象,这短短几步里包含了大量的细节和细微差异,但它们也是制定摄像机优化方案的最佳切入口。

场景测试

为了测量多个摄像机的性能成本,我们来用一下大家都喜欢的测试对象:旋转方块!从后往前,每个测试场景都有:

  • 一个由旋转方块组成的3D网格阵列,网格的每个截面都由一个10x10的方块阵列组成。截面的数量是可以调整的,这个值在本文中称为“负荷量(load factor)”。
  • 一个投射柔和阴影的方向光。
  • 2张带有面板的“game”UI画布,可模拟手机游戏中的弹出窗口。
  • 一张单独的“overlay”UI画布,用于控制测试。

完整的测试项目可在我们的Accelerate Solutions Games samples GitHub存储库中找到

Single Camera Test Scene
测试场景

我们通过修改方块的数量(负荷量)来模拟游戏中的不同情形。第一种情形的负荷量较低,模拟了类似于游戏大厅的场景。第二种情形的负荷量较高,模拟了更为繁重的游戏情形。

Exploded view of the test scene
测试场景的拆解视图

为了取得有意义的实验结果,所有摄像机配置下的场景内容都保持相同。基本的场景包括了Main Camera主摄像机、旋转方块和控制测试用的UI。接着我们创建了四个包含“game” UI和不同摄像机配置的场景:

  1. 只带有Main Camera的高性能场景。“game”画布被设置为“Screen Space - Overlay”。
  2. 两张“game”画布被设置为“Screen Space - Camera”,并分配给了第二个摄像机。这种配置在游戏中比较常见。
  3. 两张“game”画布被设置为“Screen Space - Camera”,并分别分配给了两个摄像机。该配置模拟了使用多个摄像机构成UI的情形。
  4. 第四个场景类似于第三个场景,但多了一个摄像机。该摄像机的Culling Mask(剔除遮罩)被设置为“Nothing”,它并不会渲染任何东西。

每个测试场景都是在基础场景的基础上加载的。我们还使用了Culling Mask来保证没有对象会被一个以上的摄像机渲染。

渲染管线

渲染管线是指场景中摄像机生成图像的过程。在过去,Unity仅带有一个内置的渲染管线用于场景渲染。自2018.1起,Unity推出了可编程渲染管线(SRP),允许开发者用C#脚本控制渲染,拓展了渲染的可能性。通用渲染管线(URP)与高清渲染管线(HDRP)是Unity基于SRP打造的两种新渲染管线。

在本系列中,我们将主要研究内置渲染管线和URP摄像机的性能开销,因为这两条管线支持移动设备。而HDRP并不支持,所以本次测试将忽略它。排除HDRP的另一个原因是其种类繁多的配置选项,过于详细的配置使得我们很难在测试时做出公平、有意义的对比。

URP引入了Camera Stack(摄像机堆栈)的概念,它是指一种由Base Camera(基础摄像机)和一个以及上的Overlay Camera(叠加摄像机)组成的配置。我们在URP上的测试就采用这种方法来设置摄像机。关于如何借助程序在运行时创建和修改Camera Stack的细节请参考Manager.cs演示脚本。

测试配置

我们使用了Unity 2020.3.11f1和IL2CPP开发版进行了测试。测试运行于Unity的内置渲染管线和通用渲染管线上。每条渲染管线会分别进行多次低负荷与高负荷测试,我们将在每台设备上截取16张分析器截图。测试使用的五种设备包括:

  • 谷歌Nexus 5
  • 三星Galaxy S7 edge (G935F)
  • 三星Galaxy A20e
  • iPhone 5s
  • iPhone 7

我们使用了Profile Analyzer软件包来获取主线程300帧记录的平均值。

设备性能备注

在内外各种因素的影响下,我们往往难以可靠地衡量设备性能,智能手机的过热保护和非对称CPU核心更是让测试难上加难。而Unity移动端团队编写的“Mobile Performance Handbook: Thermal Stability”为克服以上困难提供了宝贵的经验。

Avoiding thermal throttling with a cooling pack
使用外置冷却包避免过热保护

到这里,第一篇关于在摄像机上优化游戏性能的博文就结束了。测试结果、摄像机使用模式反例、多摄像机使用时机及最终测试结论等更多内容将在三周内放出。 

若想现在就了解余下的内容,可以在此处立刻下载完整的PDF版电子书

2021年9月23日 类别 游戏 | 8 分 阅读

Is this article helpful for you?

Thank you for your feedback!

涵盖的主题
相关文章