在本文中,我们将介绍Epic的技术美术和工程师如何开发出这一巧妙解决方案,从而确保《堡垒之夜:大逃杀(Fortnite Battle Royale)》(FNBR)中的建造和破坏元素玩法和视觉效果对于不同平台上的玩家都毫无二致。
一致性非常关键
建造和破坏物体是FNBR中的重要玩法,例如,破坏汽车以搜集用于建造梦想堡垒的资源,或者匆忙建造墙体以抵挡敌人的火力。
实现跨平台运营时,Epic极力确保不同平台上的每个玩家都有公平的机会来赢得比赛的胜利。要实现这一目标,《堡垒之夜》团队必须构想出一种可减少同一时间在屏幕上显示的绘图调用数量或物体数量的方法,用于克服建造和破坏物体这两个FNBR中最重要的机制所可能导致的性能问题。
建造模块化世界场景
要更好地理解伴随玩家造成的破坏而来的问题,首先需要了解FNBR中的建筑是如何建造的。你在FNBR中看到的每个建筑都是用一系列模块化部件建造的,可以快速将这些模块化部件拼接起来,搭建所需的任何建筑物。这一模块化建造方法还可以帮助减少所需的独特资源的数量,节省内存等宝贵资源。这是因为,只要通过不同的方式搭配不同材质和纹理重复使用各种模块化部件,你就可以为建筑赋予无穷无尽的变化,而不必向内存中加载更多对象。下图是通过模块化建造方法可以实现的不同类型结果的示例。
除了其中的各种装饰和道具,上图左侧的建筑是仅使用上图右侧的九个静态网格体Actor建造的。以这种方式建造建筑也可以大大降低显示玩家造成的破坏的难度,因为只需要禁用被破坏部件的渲染和碰撞就可以将部件已遭破坏表示出来。虽然该方法对于在PC和游戏机上显示破坏非常有效,但是在移动设备等性能不那么强劲的平台上就会出现一些问题。导致出现问题的原因完全在于绘制FNBR中组成建筑的350到400个单独部件的渲染成本。从下面的GIF中,你就可以看到一个典型的建筑由多少个部件组成。
尽管这对于PC和主机完全不是问题,但对于智能手机等平台却是个问题,因为在此类平台中,构成整个场景的部件的数量不能超过1000。
现在我们已经从整体上大致了解了建筑的创建原理,接下来看看每个组件是如何构建的,因为组件的构建方式也会影响破坏的显示方式。下面的流程图对本文档剩余部分中包含的信息的布局方式进行了分解。
少即是多(已优化)
即使是FNBR中使用的模块化类型建造方法,最终也会达到同一时间在屏幕上可显示的物体数量的硬限制。该硬限制被称为绘图调用,它会带来大麻烦,因为每种可运行FNBR的平台在同一时间可显示的绘图调用数量都不同。为确保可运行FNBR的每种平台都具有流畅和稳定的帧率,FNBR中使用的每个静态网格体都包含多个细节层次(Level Of Detail,即LOD)静态网格体。LOD是一种常用的视频游戏优化方法,其工作原理是当静态网格体距摄像机一定距离时,即显示静态网格体的三角形数量较少的新版本。
上图展示了用来组成在FNBR中出现的各种建筑的众多模块化墙体静态网格体之一。当你距离墙体非常近时,将看到上图中最左侧的静态网格体。当摄像机与墙体之间的距离逐渐拉大时,将显示不同的LOD,如下面的GIF所示。
当对整个建筑应用该方法后,就会得到类似下图的结果。
在上图的左侧,你可以看到原始建筑看起来的样子,在上图的右侧,你可以看到仅使用最后一个LOD时建筑看起来的样子。虽然右侧的建筑版本是我们想要的,但是组成它的部件数量仍然过多,无法在部分平台上高效渲染。要在解决此问题的同时使玩家造成的破坏能够显示,我们需要使用一些新工具和一些传统静态网格体制作方法。
采用传统方法
在进一步了解显示玩家造成的破坏的方法之前,我们需要先来看看在每个模块化静态网格体中使用的最后一个LOD,因为它是使用特殊方法创建的。使用UE4静态网格体编辑器(Static Mesh Editor)打开一个模块化建筑部件,然后通过强制让它显示最后一个LOD,我们就会看到类似下图所示的效果:
它与一般的静态网格体看起来非常相似,但是请注意其三角形数量是12,顶点数量是18。虽然这些数值看似不起眼,但是它们实际上比使用数字内容创建(DCC)工具创建大小和形状完全相同的立方体时所能获得的值还小。下图中所示的是同一个模块化建筑部件,在DCC工具中创建好后导入到了UE4中。创建好的静态网格体具有完全相同的大小和形状,但是需要注意的是,该静态网格体的顶点数量比上图中的多了六个。
仅多出六个顶点听起来不算太多,但是累积的顶点数量会快速增多。例如,如果在一个建筑中30次用到上面的部件,那么它就会为该建筑增加大约36个额外顶点。如果用36个额外顶点乘以100个建筑物的话,你就会得到3600个需要渲染的额外顶点,而它们本来是不必使用的。为了消除这些额外的顶点,我们通过以下方式对模块化静态网格体进行了调节:
- 首先,强制每个受支持的模块化部件都不使用任何平滑组。
- 其次,设置静态网格体UV,以尽量减少UV岛状区的数量。针对该模块化部件,该盒体的正面和背面完整映射到0-1 UV空间。然后,将侧面部分焊接在一起并进行比例调整,以与该模块化部件的当前设置保持一致。
- 最后,修改法线以尽量减少垂直面上的平滑瑕疵。
完成上述所有步骤后,将新调整好的模块化部件导出,再导入以代替现有的模块化部件。然后对FNBR中每个静态网格体的最后一个LOD应用该相同的流程。
在下一部分中,我们将解释为何要这样做来显示玩家造成的破坏。
他们“如何处理”了几何体?
现在组成建筑的所有模块化部件都具有了使用了尽可能少的三角形的LOD,然后我们使用细节层次级别(Hierarchical Level of Detail,即HLOD)工具来生成建筑的新版本,其效果如下图所示。
该新版本的建筑,称为Medium HLOD或MHLOD,将所有最后一个LOD结合起来组成一个静态网格体和纹理。这大大减少了用来显示建筑所需的三角形的数量,从50820个减少至仅需2880个。这带来了巨大的性能改善,尤其能令智能手机等低端设备受益。该新版本的建筑只在低端设备上且仅在玩家距离建筑大约30米时显示。这也有助于减少建筑使用的材质的数量,从而进一步有助于减少建筑需要渲染的资源的数量。
从远处查看
尽管以下信息与玩家造成的破坏无关,但了解这些内容总是有益的。玩FNBR时,你可能已经注意到了,查看远处的建筑时,破坏可能并不会显示。这是因为你看到的最后一个LOD是使用代理几何体工具生成的。代理几何体工具是我们内部开发的新工具,用以替代Simplygon,可用于进一步减少建筑的MHLOD版本的三角形数量。尽管该版本的建筑不显示玩家造成的破坏,但是却很重要,因为它有助于降低建筑距离摄像机很远时建筑的渲染成本。当针对该示例中使用的MHLOD版本的建筑运行代理几何体工具后,建筑的三角形数量从2880个减少到412个。从下图中可以看出,仅使用412个三角形时,建筑的视觉效果确实不怎么好。
但是请记住,仅当玩家在很远处查看时才会显示412个三角形的建筑版本,所以玩家很难发现建筑其实具有如上图中所示的效果。要更好地了解这一切是如何结合起来的,请查看下面的GIF。在该GIF中,我们将看到建筑从三角形数量最多的版本逐渐变成三角形数量最少的版本,正如玩家在游戏时会看到的那样。
对于建筑是如何建造的,所使用的工具是什么以及为何使用这些工具,我们已经略知一二,下面我们将了解一下这一切是如何从构想转化为可用于生产的工具的。
技术美术大显身手
现在我们已经更好地了解了建筑是如何建造的,我们需要了解一下如何将破坏应用于建筑,使得当MHLOD网格体出现在视野内时破坏能够显示。这背后的关键驱动因素之一是需要在不对MHLOD建筑做任何改变的前提下显示玩家造成的破坏。之所以有这一考虑,原因在于更改或替换部件来显示玩家造成的破坏会抵消创建建筑的MHLOD版本带来的好处。由于这一问题解决起来并不容易,我们将请求特殊类型的开发者提供协助,这一特殊类型的开发者就是技术美术。
如果不清楚技术美术扮演的角色,我们在此说明一下,技术美术(简称TA)是美术、程序员和设计师三合一的角色。从修复复杂的材质问题到对蓝图进行调试,TA能够解决许多开发过程中出现的问题。因此,TA经常会负责开发一些相对复杂的问题的解决方案,因为他们通常更加了解创建视频游戏所需的所有系统和工具是如何相互关联和配合工作的。对于这一特定任务,我们需要寻求TA的帮助,以将问题分解成最小的组成部分,便于创建简单却完善的解决方案。
分解问题
当尝试为这样的问题寻找解决方案时,需要做的第一件事情就是将问题分解成若干基本部分。通过这种方法你可以更好地了解涉及到的所有部分并取得微小但是却成功的进展。将这一点考虑进去后,TA将在MHLOD建筑上显示破坏的问题分解成以下组成部分:
- 首先,我们需要将称为HLODDestructionIndex的新属性添加到所有建筑使用的BuildingWall类。
- 然后,在构建HLOD时,我们会为建筑使用的每个Actor分配与顺序无关的索引。
- 接下来,每个建筑基础都需要一个足够大的渲染目标,确保每个可破坏的部件有1个纹素。
- 这一步骤完成后,我们就需要修改将网格体融合与HLOD配合使用的方式,以添加复制最大LOD并将自定义顶点颜色应用到新生成的静态网格体的能力。
- 注意,应该对顶点颜色进行量化,使得使用R、G和B得到的值为65k,这应该能满足我们的需要而有余了。
- 当建筑的墙体或地板等部件遭到破坏时,我们将读取HLODDestructionIndex值并将黑色写入分配给它的纹素。这将使建筑部件照常被破坏掉,而HLOD网格体不会经历状态变化,但是看起来已被破坏掉了,而我们所做的只是发出包含每个破坏事件1个像素的绘图事件。
- 最后,在材质中,如果纹素读数为零(已被破坏的片段),我们提取打包在顶点颜色中的ID,并使用它来查找破坏纹理,然后将顶点重叠到原点(例如,缩小为零)。
现在TA已经具有了行动计划,他们可以着手在UE4中构建原型,从而了解该方法是否有效,或者是否需要返回到可检验的绘图板来修改。
对于TA来说幸运的是,上述方法非常管用,他们做到了在不增加任何额外渲染开销的情况下就将MHLOD静态网格体破坏掉,如以下GIF所示。
现在TA的原型可正常工作,他们可以将原型交给工具程序员,让他们将它变成真正的生产工具。
重新构建
现在原型已经构建、测试并多次重做,以至于原型与原始构思已经很难分辨,然后它会被交给工具程序员,让其使用C++重新构建。我们之所以要使用C++对它进行重新构建,是为了确保尽可能提高它的运行速度并使它尽可能优化。使用C++重新构建该工具也使所需属性能够归入现有UI中的合理位置。在所有工作都完成后,我们可以在游戏中对它进行测试,如以下视频所示:
你可以使用的工具
总而言之,我们希望本文有助于你更好地了解Epic的技术美术和工程师如何解决伴随着跨平台游戏而来的与破坏有关的问题。如果没有他们开发的巧妙解决方案,可能就无法让玩家们在FNBR中造成一致的破坏。
最棒的一点是,本博客文章中提到的工具已在UE4 4.20发行版中推出,我们迫不及待地想看看虚幻引擎开发者社区将会如何使用它们。
要了解更多与这些工具有关的信息,请参阅以下链接:
代理几何体工具 - 代理几何体工具集的开发目的在于提供提高虚幻引擎4项目性能并使项目的视觉效果质量不受影响的方法。
细节层次级别(Hierarchical Level of Detail) - 细节层次级别(Hierarchical Level of Detail,简称HLOD)工具有助于减少需要为场景渲染的Actor的数量,同时可降低每帧的绘图调用的数量,从而提高性能。