查看原文
其他

《Suzy Cube》性能优化经验分享:巧用自定义剔除

2017-09-17 Unity官方 Unity官方平台

游戏开发中在特定时间控制关卡中指定部分显示的方法,对于实现最佳游戏性能是极其重要的。今天将为大家分享Louis-Nicolas Dozois团队使用Unity引擎制作的3D游戏《Suzy Cube》的开发经验,巧妙运用自定义剔除系统优化游戏性能。

 

您需要知道的剔除系统

可见性剔除(visibility culling),是一个只渲染游戏世界中玩家当前可见部分的过程。Unity中内置了两种方式来实现此过程,视锥体剔除(frustum culling)和遮挡剔除(occlusion culling)。视锥体剔除是剔除所有不在摄像机视野内的物体,默认是开启的,但是它在3D游戏中的剔除力度是最小的。遮挡剔除允许您根据场景中的静态对象预先计算可见性数据来补充平视锥体剔除,从而允许引擎运行时计算出在物体后面的物体,以此从渲染列表中剔除更多物体。

 


在Unity中,视锥体剔除不能被关闭,当然我们也不想关闭它。遮挡剔除则需要一些设置,需要一定的性能和内存开销。在游戏《Suzy Cube》里面我们没有使用遮挡剔除的原因有以下几个:

  • Unity中的遮挡剔除非常适用于让游戏玩家在关卡中自由漫游、环顾四周。然而在《Suzy Cube》中,摄像机在整个关卡中都被严格的控制着。这意味着,作为一个设计师,我们可以更容易地预测什么内容在什么时候是可见的,所以我们的剔除系统可以做的更自由。


  • 影响游戏性能的除了渲染之外,还有好多其他因素,特别是在移动设备这样的低规格硬件上运行时。我们写的剔除系统虽然极其简单,但是它不仅可以控制物体的可见性,也可以控制物体的显示和隐藏。这意味着被剔除的物体就不会占用多余的CPU资源,特别适用于场景中的敌人们带有复杂的脚本和动画的。因为如果让这些复杂角色同时运行可能会让帧率急剧下降。


下面就为大家分享游戏《Suzy Cube》中是如何使用剔除系统的。

 

游戏《Suzy Cube》中的剔除系统

游戏《Suzy Cube》中的剔除系统是极其简单的。它的核心功能是:只检查Suzy是否在一个特定的剔除区域内,并相应的打开或关闭该区域中的内容。

 

我们把关卡分为几个部分,组成每个部分的物体都位于一个叫做“culling zone”的物体下。


剔除区域和剔除触发器的检视面板

 

剔除区域放在自己的剔除触发器之下。如上面截图中的黄色区域显示,当游戏运行时,剔除触发器的工作是基于玩家是否在触发器的边界之内,来判断是否开启或关闭剔除区域。因为关卡中组成每个部分的物体都是剔除区域的子物体,当您离开触发器的边界,它们将会随它们的父物体一起隐藏。


在我们开发此系统第一个版本的时候,我们是手动定义剔除触发器边界的。之后,还扩展了剔除触发器的功能,以便在编辑模式下自动构建触发器的边界,以及控制区域的偏移和大小。初始边界通过以下方式进行自动构建:遍历剔除区域中的每个物体并重新调整触发器的边界以包含所有物体。这个过程的最后一步,我们得到的是一个完美贴合坐标轴的盒子,它可以完全包含所有物体并添加偏移量或加入额外的边距。


这些剔除区域非常容易设置和使用。对于熟悉Unity的人,我们创建了一个只包含剔除区域触发器和剔除区域父物体的预置体。触发器设置了合理的填充值,所以,只需要简单地将预置体拖拽到场景中并简单地在剔除区域下添加子物体将关卡分为几部分,便设置好了一个触发器。使用默认值就可以很好的工作。设置完毕后,我们将会开始调节个别的剔除触发器偏移,扩展触发器使可见物体不会挤出触发器,或者进行进一步性能优化。

 

剔除系统实现的效果

使用剔除系统以后可以提升一倍以上的帧率。

 

编辑器中没有使用剔除的视图


编辑器中使用剔除的视图

 

这是编辑器中关卡1-1的开始视图。不使用剔除,所有的关卡都是显示的,都被渲染并占用CPU资源。开启剔除后,只有开始部分和平台第一部分是显示的。这样做有很大的不同,尤其是在移动设备上运行时。

 

我们在最初编写剔除系统时,意识到剔除区域可以作为其它剔除区域的子物体。话句话说,我们可以在大的剔除区域嵌入小的剔除区域。当然,大家可以不用这样做,只是我们实在找不到理由不这样做。


最近,当制作到关卡4-3时,我将此假设进行了实践,首次使用了嵌套的剔除区域。


关卡4-3设置的嵌套剔除区域

 

关卡设置的像一个连续的高塔。事实上,这是三座较小的塔楼,并排放置。每个塔楼由几个竖直部分组成,每个有其自己的剔除区域。每一个竖直区域包含四个嵌套的剔除区域,用于方塔的四个面。大的竖直剔除区域可以确保只有相关的区域才是可见的,并且确保游戏不会把时间浪费在玩家根本看不到的,在对面塔楼里的素材的渲染和计算。

 

使用此方式组织剔除区域让我们可以更进一步地优化关卡性能。我们并不需要去显示一个可视区域中的所有物体,如下图所示:



尽管此关卡中的后半部分在远处是可见的,并不意味着右上角在低洼处的三个敌人需要显示。敌人比静态几何物体消耗更多CPU资源,在玩家接近之前剔除它们,就可以将帧率每秒提高几帧之多。

 

通过使用一个允许我智能地控制哪个部分在任何特定时间是显示和可见的系统,我可以重新获得宝贵的GPU和CPU资源,我可以花费在真正重要的事情上,比如和玩家的紧密互动。

 

远处小的装饰性物体如草丛或者小石头,有时候根本看不到。如果剔除它们,就意味着我可以在离相机近的地方添加更多东西,这在关卡外观上能起到了很好的效果。


最主要的是这套系统可以用在所有的平台上。如果您的游戏已经可以在一台高配PC上很好的运行,想象一下,如果使用这种剔除方式,那么游戏表现将会更加出色 。系统将不会再把资源浪费在计算或者渲染看不到的物体上,而是强化玩家实际关注的眼前事物。


结语

今天为大家分享的内容都是基于游戏的玩法和相机的控制方式。对制作飞行模拟器或第一人称射击游戏的作用不会太大。


后面我们还将继续分享更多关于游戏性能优化方面的内容在Unity官方中文社区(unitychina.cn),请保持关注!

 

推荐阅读

Unity支持ARCore,为移动AR再下一城

Unity实现更佳光照效果的7个技巧

Unity 与 ARkit 开发-基础篇

Unity 教程 | 使用UGUI ScrollRect制作动态相册

游戏设计分享 | 使用Unity高效改善游戏反馈机制


近期Unity官方活动

9月19日,上海,Unity与Qualcomm联合举办技术开放日,火热报名中。


9月20-25日,“Unity全球技术校园行”将为你揭开顶尖佳作背后的神秘面纱。


9月,Unity面向莘莘学子特别推出Unity Plus加强版开学季专属特惠,及Asset Store资源商店5折促销。


点击“阅读原文”进入Unity官方中文社区

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存