【GDC2024】《三角洲行动》双端高品质的一体化生产管线与技术

2024-04-30  本文已影响0人  离原春草

三角洲的引擎版本是4.24,其硬件基线为:

  1. PC为GTX 650
  2. Android为Adreno 512

PC版本性能标准给出如下:

  1. Base Pass的DP:从500 ~ 1200
  2. 同屏总面数:1M ~ 3M
  3. Base Pass面数:0.6M ~ 1.4M
  4. 局部光源数:3 ~ 5

移动端性能标准:

  1. 总DP:250 ~ 650
  2. 场景总DP:180 ~ 510
  3. Base Pass DP:140 ~ 390
    特效DP:10 ~ 40
    面数:3k ~ 6k
    场景顶点数:35w ~ 100w

这里对一体化的定义是:

  1. 相同的资源
  2. 同一批开发同学
  3. 同一套制作开发工具

要求做到:

  1. 一次性的编辑制作(绝大部分情况下)
  2. 玩法体验的一致
  3. 兼顾多平台性能

移动端+PC的跨平台挑战 & 解决方案:
1.硬件差异导致的性能差异
a.不同设备运行不同的renderer(deferred + forward)

2.多平台联动、协同体验,要求资产跟玩法的同步发行
a.通过一套管线,实现多端的同步研发与发布

多端的支持,可以拆分为两个部分:
1.生产管线:美术资源的制作
2.运行时体验:包括gameplay跟性能优化

资源制作管线的挑战在于如何用一套资源实现多个平台的支持,其中涉及到了资产的制作方式,LOD、Shader等的管理,这里面会面临很多的问题:

  1. 资产制作层面
  1. 离线优化层面
  1. 运行时优化层面

从上图可以看到,针对某一类固定资产,有些数据是可以跨平台复用的,有些则是不能,如果我们希望生产管线能够自动适配多个不同平台,就要将不能复用的数据拆出来,这对引擎改造来说是一项大工程。

此外,针对不同的资产类型,处理的方式也是完全不同的,从而进一步加剧了这个问题。

展开来说:
1.针对同一套材质,需要考虑如何输出不同平台的两套shader,而且,这里还需要考虑不同渲染管线的区别
2.Mesh的LOD虽然在复用的处理上比较简单,但是FPS游戏希望在多端上的碰撞表现是一致的
3.贴图的分辨率以及压缩设置也需要做不同的处理(这个看起来相对简单)
4.还需要将当前平台不用的数据从cook列表中剔除出去

在管线的选择上:
1.PC+高端移动机型,采用的是延迟渲染管线
2.中低端移动机型,采用的是前向渲染管线

为了通过同一套材质来应对上述设备、管线的差异,DFM提出了一种叫做Virtual Material System的东西,这个东西有如下特性(看起来更像是一个大杂烩,而非一套从最初就完整设计好的系统,应该也是初次使用):
1.将资源与shading解耦
2.支持对资源的自定义组织,比如贴图通道的remapping
3.支持对不同平台、不同quality level的配置(相当于性能的分级)
4.提供了一套模块化的材质函数模块以实现材质逻辑的复用

在编辑器模式下,美术跟TA同学会为对应的资源(模型)配置好母材质,并编辑对应quality level的效果,在cook的时候,会将这个材质烘焙成不同的材质实例,并完成这个材质实例与资源的关联。

下面看看这个系统是如何工作的,系统组织逻辑如下图所示:
1.整个系统分为三个模块,分别是Material Layer、Virtual Material Template以及Virtual Material Instance
a.Material Layer是整个系统的核心模块,大部分的功能都是由这个模块承接
b.Template模块可以认为是对UE母材质的封装,基于这个Template,美术跟TA同学可以完成材质的编辑与配置工作
c.Instance是整个系统的产出物,在cook的时候会被烘焙成不同平台的Material Instance
2.Material Layer包括三个部分,分别是Data Provider,Effect Layer以及Blend Controller
a.Data Provider负责材质的数据部分,包括搜集贴图、暴露贴图插槽以及管理不同quality level的资源
b.Effect Layer包含两个功能,分别是负责材质的效果逻辑以及与上一层的blend(?)
c.Blend Controller则是负责一些复杂的混合逻辑

基于这个设计,就能实现shader跟mesh之间的解耦,从而实现同一个mesh在不同平台上的不同shader实现

下面来看下,针对不同平台上,怎么做到同样的碰撞表现。

DFM中将模型分为6级LOD,其中PC会使用完全的6级(?),而移动端则只使用后面3级。

可以看到,移动端上的Mesh LOD Bias为3,因此mesh的精度相对于PC会有所下降,因此部分细节会丢失,如下图所示,图中的围栏从LOD3的时候就会被移除:
1.如果围栏对应的碰撞还在移动端上保留,那玩家的体验就会下降
2.如果碰撞移除,那么跟PC的体验就会不一致
3.如果PC跟移动端的碰撞都移除,就会导致效果上的不真实

这里采取的解决方案是为不同平台设计不同的碰撞数据,这里没有详细描述解决方案(说是TA的talk中有更多描述,后面有时间可以来补充一下)。这里想到的一个方案是在LOD减面的时候,需要考虑碰撞数据的影响,对于会影响碰撞表现的部分,在减面的时候要予以保留。

这种为不同平台进行数据定制的策略不仅仅用在碰撞上面,对于其他的一些资产如天空盒的贴图与压缩配置、lightmap的相关配置,也是采用同样的策略。

讲完了资产编辑与准备,接下来看看场景的表现与性能,在这里,既需要兼顾场景的丰富度,也需要照顾移动端性能下的加载范围

为了实现上面所述的兼顾,这里的思路是将场景的资源拆分为两个部分:
1.共享层,存储的是各个平台共用的数据
a.出于玩法的统一,对于玩法有影响的数据需要放到这个地方
b.出于保持主体视觉的一致,场景的基本布局相关数据也要放在这里
2.平台层,存储的是各个平台特有的数据:出于性能的兼顾,一些偏表现层的数据则可以考虑放到这里

对于共享的数据,也需要针对平台的不同做一些处理,如下图所示,共享数据会被分为HD & Mobile两类。

为了减少美术同学的工作量,这里的另一个原则是尽量将数据往共享层挪,基于这个原则,通过PCG或者其他自动生成工具输出的数据都会自动被拆分为多个平台的

下面看下不同平台下的效果对比:

大型项目的另一个问题,如何实现海量资源的高效管理,包括如何维护资源的规范以避免混乱,如何降低数据的冗余(比如通过对资源的扫描,找出重复的贴图或材质等)以及如何保障资源的正确引用等,常用的策略是提供相应的检查与预警工具

针对不同平台,在运行时的Streaming配置也需要做不同的处理:
1.为不同平台、不同资源类型设置不同的加载距离
2.对于开镜时的处理也会有所不同,PC是全加载,在开镜的时候切换可见性;移动端则是在开镜的瞬间加载在Frustum内部的数据(性能?)

接下来看看DFM针对Runtime level做了哪些优化:
1.一些debug的actor会从runtime levele中移除出去
2.物理模拟跑在DS上,需要将之从Mesh中抽取出来,并按照一定规则做合并
3.为了降低植被的内存&drawcall消耗,针对不同的foliage类型,做了不同的streaming设置
4.地形被替换成基于CDLOD实现的方案
5.由于使用的引擎是UE4,不能直接使用UE5的World Partition,这里就直接采用了类似的基于grid划分的方式来对mesh actor进行分块streaming

如下图所示,上述过程中的部分优化是集成在自动构建环节中的:

其中针对移动端,还做了静态合批以减少Drawcall:
1.先对需要合批的模型进行合并前的确认,包括材质、贴图等是否符合合并规则
2.之后确认合并后的数据的有效性,比如顶点数是否超上限、贴图是否超出最大分辨率以及距离是否合理(指的是待合并的模型之间的距离?)

静态合并的好处是可以保证数据有较好的局部性,同时提升渲染时的性能

接下来看看DFM在渲染上的一些策略、如何在多端上实现统一的gameplay效果以及常用的一些性能工具:

虽然不同平台的渲染管线是不同的,但是项目组希望不同平台都具有相同或者相似的主要特性,下面给了两条管线的框架(如果想要复刻这套思路,我们也应该有一张自己的图,图中甚至需要给出不同级别的设备的差异):

先看光照部分,为了实现统一的光照效果,对于主要的特性而言,在不同平台上的实现方式会有所不同,比如sky occlusion是多端共享的,但是AO的实现策略却有所不同,移动端走烘焙,PC则使用的是GTAO以及DFAO(距离场),基于这种一致性设计,美术同学就不需要为场景做两套设计,可以大大提高工作效率

GI方案是基于体素实现的,体素中存储的不是光照信息,而是离线烘焙的probe与权重数据(?),为了实现多端统一的效果,做了如下约束:
1.probe分布算法在多端是一致的,不同的是PC端的probe密度会更高
2.probe的数据填充逻辑是一致的
3.probe的streaming逻辑是一致的

区别体现在基于性能考虑的一些计算方式上:
1.移动端数据密度低(probe密度),GPU性能稍差,因此probe数据是在CPU完成读取,并组装成3D贴图,之后传给GPU进行采样计算。优化的重点在于如何提升CPU的读取效率(比如提高缓存友好度,优化数据压缩算法等)
2.PC上的数据密度高,不需要通过CPU中转,直接读取到GPU中,在GPU中完成数据的解压与解析。GPU的关注重点为如何提高显存的利用率,这里的做法是将probe按照稀疏的树状结构存储,此外,考虑到CPU到GPU数据传输时的卡顿,这里也做了异步处理

有了动态GI,很自然的就可以添加TOD效果,DFM的TOD是通过sequencer驱动的,多平台共用的参数存储在基础sequencer中,跟平台相关的额外参数则存储在另一个单独的sequencer中:

地形的方案是优先PC,在先进特性的实施过程中,考虑在移动端的落地:
1.看下图描述是基于Material ID实现的
2.Texture Array移动端最多32套,PC端则是256套
a.数据支持动态的增减
3.每个像素可以支持多层混合
4.采用了AVT技术,还做了运行时VT的压缩
5.在移动端上的规格为,每米大约会占用到500+个texel,以及3套材质
6.Cliff(悬崖峭壁)也是基于VT实现,采用了随机的tri-planar blend方案
7.还以米为单位存储了biome(植被)信息(染色、湿度以及AO)以提升场景的丰富度。这里的数据是用clipmap存储的,相对于完全平铺的方式,可以极大的节省内存:从133M到2M
8.用了大量的贴花与软件Tessellation
9.用80k的顶点实现了接近380k的远景效果(用的Tessellation?)

关于地形的渲染细节,在Unreal Fest 2023中有更多分享

接下来看下Gameplay一致性如何保障,这里将整体的gameplay逻辑分为三层:
1.Core feature layer:对应的是所有平台都一直的一些基础特性,比如Gameplay框架、网络模型、移动同步、武器射击以及其他的一些战斗细节。
2.Flexible feature layer:负责提供一些可以在不同平台上做伸缩控制的特性,这些特性可以基于设备的性能、quality level等来进行参数的动态调控与特性的开关
3.Platform feature layer:用于实现平台不同的特性,比如input/HUD等

关于角色动画的跨平台设计包括:
1.各平台使用同一套basic skeleton,只是PC上会增加一些额外的骨骼与动态信息
2.动画数据基于同一个角色的parent skeleton创建,因此可以在双端进行复用
a.PC上会采用更高的帧率与效果更好的压缩方式

大部分的动画特性都是双端共享的,只在部分特性上做了处理,对于这些做了处理的特性,有一些也会提供一些开关允许在高端设备上开启,比如换弹动画,在PC上是完整的动作片段,而在移动端上则是通过IK来模拟的,虽然看起来差不多:

DFM还设计了一套规划算法,来基于每台设备的性能表现与预算,动态决定哪些特性是否需要开启,总的来说,这套算法的思路跟knapsack算法类似,会需要先为每个feature指定一个权重,之后会基于feature开启后的性能消耗来对所有feature进行评估权衡,以获得最高性价比

这里还给了两个演示视频来展示这个算法的效果

DFM还设计了一套自适应的UI框架,大部分的UI数据都是包含在这个框架里的。

为了提升跨平台共用的效率,这里会将平台相关的参数抽取到framework layer(?):
1.DPI会跟屏幕分辨率有关,因此需要为不同平台做专属设计,Display Ratio、Padding也有同样的问题
2.不同平台的UI导航方式(?)会不一样,这部分会需要放在navigation layer中

DFM的目标分辨率设定是2k:
1.UI资源的原始尺寸是2k的话,在移动端上会被cook成1080P的
2.PC跟Mobile共享的资源,在PC平台会在运行时被DPI下采样为原始资源的2/3,但是会达到跟4k一样的效果(?)
3.在PC上,建议打开mipmap来避免像素的mismatch

最后看看性能工具,DFM对工具诉求是:
1.支持跨平台使用
2.不需要pre-instrumentation(代码预埋)
3.支持长时间的、可扩展的数据搜集
4.不会对运行时性能产生影响

最终自己开发了一套:

工具的逻辑可以分为三层:
1.通过一套跨平台可调用的接口实现高性能的数据采样,这个采样会结合每帧的时间消耗与自定义的数据,统计出每一帧的性能数据
2.对每个函数的性能数据与函数的堆栈进行分析,得到一帧的call tree
3.通过一个服务+既定的规则来对所有数据进行分析,这里会进行一系列的自动化分析,比如Pearson correlation coefficient(皮尔逊相关系数分析),基于这个可以统计出函数之间的关联关系

上一篇下一篇

猜你喜欢

热点阅读