大家下午好,感谢大家参加本次会议。我叫施旸,是《三角洲行动》游戏客户端开发的负责人。本次演讲原本应该由我的同事梁尚立和我一起进行。但是由于一些出行问题,他无法加入我们,所以我将独自进行整个演讲。
今天,我将分享《双端高品质的一体化生产管线与技术支撑》,涵盖了在开发《三角洲行动》过程中遇到的各种生产挑战和问题。
首先,让我们先看一个视频,以了解游戏的基本情况。
《三角洲行动:黑鹰坠落》是在90年代末和2000年代初经典的《三角洲行动》系列的续作,我们决定将其带回来,打造成一款面向PC、主机和移动设备的下一代操作员战术射击游戏。
我们的产品规模实际上非常庞大,希望为所有平台的玩家都能带来极致的FPS体验。今天,考虑到PC和移动平台之间的硬件差异,我们也会主要关注在这两个平台的跨端开发上。让我们先来看看我们所面临的挑战。
首先是性能差距很大,帧率是FPS游戏的基准。我们的目标是覆盖每个平台上的低端设备,为了更好地利用平台功能,我们决定运行不同的渲染器。另一个问题是支持跨平台数据互通,我们必须同时开发和发布内容,这也就意味着移植不是一个可行的选择。而且,分别为每个平台负责的两个独立团队在生产和维护效率方面也是不可接受的。因此,我们决定构建一个统一的端手一体开发流程。我们的目标是同一团队在同一时间交付高质量的跨平台游戏。
让我们来看一下总览,在我们决定统一跨平台开发的初期阶段,我们实际上经历了激烈的讨论,并设想了许多潜在的问题。基本上,我们将重点分为两个主要领域,一个是生产流程部分,更多关注资产和内容的制作,另一个是跨平台运行支持,主要涉及游戏开发和性能跟踪工具。
这里列出的并不是一个完整的列表,这只是其中的一部分问题,实际情况要复杂得多。今天我们无法详细讨论每个细节,但我们选择了一些我们认为重要且具有挑战性的典型问题,与大家分享一些想法和方法。
让我们从资产制作部分开始。
基本上,我们为不同类型的资产设置了不同的共享策略。但是如何构建跨平台场景是最复杂的问题之一,涉及到单个模型的制作、LOD管理、着色器管理、关卡布局编辑、性能开销甚至关卡艺术家的工作量。这是我们今天主要关注的生产流程部分。
那么,首先让我们看看在跨平台共享资产时出现了哪些问题?
对于共享资产,我们首先需要解决的问题是如何在同一材质槽中支持两套着色器。第二,我们充分利用了LOD链,但作为一款FPS游戏,我们不能容忍任何碰撞不匹配。此外,PC和移动设备之间存在着纹理分辨率和像素比的差异。这导致纹理大小和压缩设置的变化。当我们在不同平台之间共享资源时,我们需要在非目标平台上删除冗余数据,以避免内存和磁盘存储的浪费。当然,还有许多其他更细节的问题。
在同一模型中管理不同的着色器非常棘手,特别是我们有多个渲染器,我们在PC和高端移动设备上运行延迟渲染器,并在其他移动设备上使用前向渲染。为此,我们实现了一套虚拟材质系统。顾名思义,它用于虚拟化材质。它提供了解耦资源和着色器的能力,以及自定义资源组织规则(如纹理通道重映射)的能力。它还维护了多平台和多质量级别的资源配置,以及我们的模块化材质和功能重用。
在编辑器模式下,虚拟材质模板存储了不同平台和不同质量级别的基本材质信息。然后,它被实例化为虚拟材质实例,并分配给共享模型组件中的材质槽。
在运行时,在打包后的版本中,虚拟材质实例将回退到普通的材质实例,而且其中非目标平台的数据也会被去除。
下面是一个示意图,说明了虚拟材质的使用方式。数据提供器主要完成纹理数据的收集,暴露虚拟材质模板使用的纹理槽,管理不同质量级别的资源,并适配数据。效果层由两个功能组成:材质效果逻辑和与上层的混合方法。混合控制器是一个独立的逻辑层,处理复杂的混合方法。通过虚拟材质系统,我们基本上将材质与渲染器解耦,使得着色器在不同平台上甚至在同一模型组件内非常灵活。
除了材质和着色器,第二个典型问题是碰撞。让我们来看一下这个短视频。当LOD索引偏向移动平台时,我们开始丢失网格细节,在这种情况下,栏杆从LOD3开始被移除,但我们只能在网格组件中有一个碰撞数据,这将导致碰撞不匹配,对于FPS游戏来说,这是完全不可接受的。那么,我们该怎么解决这个问题呢?
解决方案实际上非常直接。我们扩展了碰撞设置,并为其添加了每个平台的数据。通过这样做,我们可以在保持一致的游戏交互的同时,适应其独特的性能限制和质量要求。
在修正了碰撞数据之后,现在PC和移动平台都具有了与其渲染模型相匹配的正确碰撞。实际上,每个平台的属性方法也被扩展到其他资产类型和对象上。例如,天空光立方图在每个平台上具有不同的纹理和压缩设置,另一个例子是相同静态网格组件的光照贴图,因为我们在同一关卡中为不同平台单独烘焙光照贴图。
关于更多资产制作的细节,我们工作室的技术美术负责人王理川在之前的演讲中从技术美术的角度进行了介绍。如果你感兴趣,可以在那里找到更多信息。(查看详情>>)
好的,一旦我们准备好了所有的资产,问题就变成了如何高效地构建一个在各个平台上都符合质量和性能标准的沉浸式场景。我们需要关注不同平台的场景丰富度以及如何管理由于移动硬件限制而产生的不同加载距离。不仅如此,在相对复杂的资源管理和编辑工作流中,我们需要在打包成构建之前识别错误。此外,一些特定的优化在不同平台上也有所不同。
总体思路是从两个方面管理关卡内容。首先,我们有基本的共享层,只包含共享的资产。在此基础上,我们将适当地拆分平台特定的内容,并让它们进入各自的专属层。另一个方面是资产类型,在右上方的图像中,我们将资产类型分类到不同的层级中,以便更好地管理。
对于需要关卡美术参与的部分,我们尽量减少相关工作量,这意味着大部分内容实际上属于共享层,并确保基本的关卡布局在各个平台上与关卡设计师的意图保持一致。然而,对于特定平台的内容仍然会进行微调或调整,例如为PC增加丰富性或为移动设备进行优化。视频中展示了关卡截图的端手对比。
对于由PCG或其他自动化工具生成的内容,因为不需要人工参与,我们完全分离了关卡组,并将其输出到每个平台。
在一个大型项目中,随着跨平台制作流程的进行,实际上增加了管理的复杂性。我们不可避免地会遇到一些人为错误和协作问题,例如放置错误的资产、错误的平台引用、纹理浪费等。为了有效消除这些错误,我们提供了一套与资产相关的故障排除工具,帮助进行错误检查、提供性能建议和数据统计。视频展示了我们如何通过分析纹理相似性来找出不必要的纹理浪费。
在所有编辑和配置工作完成后,我们不能直接运行关卡。为了满足我们的规定和性能要求,我们将所有编辑状态的关卡转换为运行时关卡。为了实现这一点,我们对运行时关卡进行了更详细的分层,如图所示,我们在PC和移动设备之间有不同的关卡划分和流式传输配置。
射击游戏中的另一个典型问题是瞄准,对于PC,我们切换关卡可见性。但对于移动设备,我们采取了一种平衡的方法,即在瞄准时只流式传输视锥内的关卡。
最终,我们的目标是拥有相同的资产、相同的关卡,但通过不同的运行时关卡实现在每个平台上稳定的性能!
让我们来看看构建运行时关卡处理的内容。
首先,需要清理未使用的Actor,通常这些都是调试用的Actor。二,为了提高专用服务器的性能,物理数据被提取和合并。三,所有的植被都被转换为每种类型的流式资产。因此,我们可以详细管理植被的内存成本和绘制调用。四,地形也被转换为CDLOD。五,根据位置和边界大小,网格被自动划分为不同的级别网格。最后,还需要处理一些其他与游戏玩法相关的数据。
我们已将整个构建过程集成到自动化工作流中。它分析原始关卡,重新分配资产,生成相应的资产类型,提取关键数据,执行特定的优化,并自动收集基本的性能统计数据。模型合批是唯一专门为移动平台定制的部分,而其他过程在各个平台上保持一致,只有不同的配置。
这是关于移动平台批处理的核心策略的简要介绍。首先,我们需要确定批处理一组模型的可行性,包括检查具有参数的材质、纹理格式、光照贴图、阴影投射和IBL。批处理还需要验证其合理性,例如顶点数是否超过限制,纹理分辨率是否能满足预算纹理集的容量,以及距离是否合理。我们最终的批处理结果展示了良好的局部空间感,并且显著减少了绘制调用。
现在让我们进入运行时支撑部分,我们将分享一些跨平台的渲染策略和功能,以及如何统一游戏开发,还有一些关于性能跟踪工具的内容。
让我们先来看看渲染部分。
如前所述,为了更好地利用不同平台的特性,我们决定运行不同的渲染管线。然而,我们仍然努力在一些主要特性上保持一致。这个图表展示了渲染方案的具体示例和细分,突出了相似性和差异性。在确保整体一致性的同时,我们还在底层技术上进行差异化开发,以满足各种质量和性能要求。
在光照方面,我们确保光照组件的一致性,从而在各个平台上实现类似的光照感知。为了实现这一点,我们采用了一些底层技术,为相同的光照组件实现了不同的方法。例如,天空遮蔽由我们的跨平台全局光照解决方案统一提供。但是,对于更详细的环境光遮蔽(AO),移动设备更多地依赖于纹理烘焙,而PC则利用GTAO和距离场AO。通过在光照组件上保持一致性,我们的光照艺术家不需要担心跨平台差异。
对于全局光照(GI)部分,我们的算法是基于体积的,但体积中的体素不存储任何光照信息。相反,它们存储了稀疏分布的探针和离线拟合的权重。
为了降低整体复杂性,PC和移动设备之间的共同点包括:
1. 相同的离线探针分布算法(但密度不同)。
2. 相同的数据拟合算法。
3. 相同的基于块的流式传输逻辑。
差异主要在于不同的优化方向。
移动设备的数据密度较低,因此离线数据由CPU读取并组装成3D纹理,GPU只执行简单的采样以最小化GPU负载。因此,移动设备上的优化更加关注CPU读取,增强缓存友好性和数据压缩,以减少内存成本和磁盘存储。
PC的数据密度较高,因此数据直接加载到图形内存中,GPU实时读取拟合的权重,并在那里动态解压光照数据。PC上的优化更依赖于数据存储格式,我们使用树状结构和稀疏存储来最小化运行时图形内存。此外,还添加了更多的异步机制,以防止从CPU发送数据到GPU时出现卡顿。
一旦我们实现了光照的一致性,我们可以在更高层次上封装一些统一的参数接口来实现时间流逝(TOD)。在这里,我们使用一个序列管理器来驱动所有的TOD参数。大多数常见的参数都在基础序列器中实现,而微小的平台差异则由子序列驱动。
另一个重要的部分是地形。当我们在PC上实现一些先进的技术以获得更好的质量和性能时,我们始终考虑到移动设备的适应性,并最终成功将其中的一些技术带到移动平台上。
我们为移动平台进行了许多优化,以实现与PC相似的质量。
1. 自适应动态纹理数组为整个世界带来了32种材质,但运行时只需8种材质的内存成本。
2. 我们使用随机三平面混合实现了悬崖渲染,首次使用VT技术,并首次将其引入移动设备,极大地提高了地形质量。
3. 为了在移动设备上实现每米湿度和色调,我们添加了剪辑贴图纹理流式传输,它可以将大型纹理的内存成本从133MB减少到不到2MB,几乎降低到1%,并帮助我们提高移动设备上的地形多样性。
4. 对于地形的远景视图,我们还实现了具有380K顶点细节的地形,而性能成本仅为80K顶点,而不会丢失任何质量。
更详细的信息,请查看由徐云瀚在Unreal Fest 2023上的演讲。
好的,游戏玩法部分。我们也为游戏玩法开发构建了许多跨平台解决方案,但今天我们主要谈论战斗和用户界面部分。
在核心战斗开发中,我们仍然采用了一种集成的方法,适用于PC和移动平台。整体战斗特性分为三个层次。核心特性层是与平台无关的基础,包括游戏玩法框架、网络模型、移动同步、武器射击和其他战斗细节。灵活特性层提供可扩展的跨平台配置,我们可以根据性能预算和质量水平动态确定启用哪些特性。平台特性层处理平台特定的适应,如输入控制器或HUD交互。
在我们的项目中,基本骨架在PC和移动设备之间是共享的。
如图所示,骨骼物理模拟的复杂性也有所不同,我们在PC上添加了更多的子骨骼和动态细节。动画的创建基于角色的相同父骨架,确保大多数动画片段在各个平台上保持一致并可重用。然而,PC上的动画具有更高的动画帧数和更好的压缩设置。
在动画特性方面,大部分特性同时针对PC和移动平台进行开发。考虑到性能限制,我们还在移动平台上提供了一些替代方案,通过牺牲一些质量来实现相同的效果。例如,换弹动画,我们在PC上提供完整的动画片段,但在移动设备上使用IK来模拟相同的效果,实际上很难区分出差异。
为了根据性能预算动态确定启用哪些特性,并在每个设备上实现最佳整体性能,我们使用了一种规划算法。实现方法涉及使用规划算法,考虑特性的静态质量和动态运行时条件,定义每个特性的“价值”。然后,在现有的约束条件下选择最佳的特性集合,包括性能限制和特定特性的约束。整体规划算法有点复杂,但基本思想类似于背包算法。通过有限次迭代,我们旨在找到满足约束条件的最佳特性组合。
让我们来看一下最终的规划结果:在左侧的视频中,我们可以看到在不同预算配置下多个玩家的移动质量。随着预算的增加,玩家的不真实移动的可能性减少。而远处的角色在移动行为中不会牺牲诸如地板检测之类的特性。自然而然地,PC可以启用更多和更高质量的特性,而移动设备只能为少数几个角色启用有限的特性。
右侧的视频展示了游戏中的最终结果。在游戏中有64个玩家,存在着相当大的性能压力。它有效地平衡了性能预算和游戏呈现,实现了流畅的结果。
对于用户界面部分,也需要大量的跨平台工作量。因此,我们的大多数UI页面是通过自适应UI框架共享的,而一些重要系统是单独开发的。
为了提高共享UI页面的效率,我们将平台特定的参数提取到框架层。首先,DPI曲线被分离出来以更好地适应屏幕尺寸。PC需要处理更广泛的显示比例范围,因此我们添加了比例约束以防止异常显示问题。在视觉设计阶段,我们以一个平台作为基准,然后在一定的规则下对其他平台进行调整。不同的平台具有不同的UI导航方法,因此我们将它们提取并分离到导航层中。我们还提供了各种快速调整选项,例如填充、缩放、调整大小和节点裁剪,以进一步微调最终的UI。
为了更好地共享UI资源,这是我们的原始资源标准,我们选择2K作为基本分辨率。在cook过程中,原始的2K资源被压缩到1080P用于移动设备。但是对于PC,资源在运行时通过DPI动态缩小到66.67%,以实现与4K分辨率相同的效果。一个小提示是在PC上启用mipmapping以避免像素不匹配,以避免闪烁。请参考右侧的视频进行比较。
好的,最后一部分,性能。
为了更好地监控和分析与性能相关的问题,我们尝试了各种工具,但似乎没有一个符合我们的要求。我们需要的是一个跨平台工具,不需要任何预先插桩,支持长时间和广泛的数据收集,而不会影响运行时性能。因此,我们开发了自己的跨平台性能监控和分析工具,名为metaperf。
性能捕获的整个循环由3个阶段组成。在记录阶段,我们为所有平台实现了高性能采样器:通过结合每帧的帧时间和自定义数据,我们可以获得每帧的各种游戏状态;然后,通过处理每帧的时间戳并合并样本中的所有调用链,我们可以获得一帧的完整调用树。在最后的分析阶段:我们实现了一个基于规则的自动化分析监控服务。这包括各种自动化分析方法,如皮尔逊相关系数。通过比较两个曲线之间的相关性,我们可以确定性能指标中每个函数的相关性。
metaperf工具已经在我们的项目中广泛使用,并收集了10000多个游戏记录。帮助我们识别和解决了1000多个与性能相关的问题。
好了,总结一下。没有正确的解决方案,只有合适的解决方案,我们分享的只是实现高质量和高性能跨平台开发的一种可能方式。您应该根据产品和团队的情况找到解决方案。工具对于开发效率来说非常重要。希望这次交流能给您一些启发。
特别感谢整个《三角洲行动》开发团队,几乎每个人都提出了建议和反馈,使我们能够不断迭代和优化流程,使其变得更好。