三角洲的引擎版本是4.24,其硬件基线为:
- PC为GTX 650
- Android为Adreno 512
PC版本性能标准给出如下:
- Base Pass的DP:从500 ~ 1200
- 同屏总面数:1M ~ 3M
- Base Pass面数:0.6M ~ 1.4M
- 局部光源数:3 ~ 5
移动端性能标准:
- 总DP:250 ~ 650
- 场景总DP:180 ~ 510
- Base Pass DP:140 ~ 390
特效DP:10 ~ 40
面数:3k ~ 6k
场景顶点数:35w ~ 100w
这里对一体化的定义是:
- 相同的资源
- 同一批开发同学
- 同一套制作开发工具
要求做到:
- 一次性的编辑制作(绝大部分情况下)
- 玩法体验的一致
- 兼顾多平台性能
移动端+PC的跨平台挑战 & 解决方案:
1.硬件差异导致的性能差异
a.不同设备运行不同的renderer(deferred + forward)
2.多平台联动、协同体验,要求资产跟玩法的同步发行
a.通过一套管线,实现多端的同步研发与发布
![](https://img.haomeiwen.com/i19200103/6e48ecddde84556c.png)
多端的支持,可以拆分为两个部分:
1.生产管线:美术资源的制作
2.运行时体验:包括gameplay跟性能优化
![](https://img.haomeiwen.com/i19200103/45ae795ed93684ef.png)
资源制作管线的挑战在于如何用一套资源实现多个平台的支持,其中涉及到了资产的制作方式,LOD、Shader等的管理,这里面会面临很多的问题:
- 资产制作层面
- 双端是否共用同一套关卡
- mesh、texture如何应用到多个平台: LOD起始Index、切换距离;物理碰撞的精度;材质复杂度 —— 做好配套的资源规范工具(LOD切换距离、顶点密度、贴图尺寸、材质复杂度等)
- 地形数据如何实现多平台的兼容
- 如何保证双端的物理表现一致
- 如何保障复杂的资产制作约束规则下的生产效率
- 同时研发端游 & 手游,人力&优先级如何权衡:白盒 -> 端游效果&性能 -> 手游效果&性能 -> 双端兼顾
- 如何实现多端表现的高效debug(快速预览)
- 离线优化层面
- 如何从编辑关卡转化为具有最佳性能表现的运行时关卡(兼顾PIE跟构包)—— 在Cook阶段做了很多处理,包括:
A. 构建针对不同平台的地形数据(heightmap之类)
B. 构建针对不同平台的植被数据
C. 场景物件处理(过滤不需要的component,完成物件到grid、layer的分配,合并ISM,阴影优化,SOC遮挡物优化),结果以增量形式存在(?),这里物件是基于剔除时的screensize来设置其所属的grid/layer的(仿造TextureGroup的概念,增加了一个MeshGroup的概念,方便实现对某一类数据的批量处理) - 不同平台的运行时关卡该如何做分别的处理
D. 构建场景物理数据
E. 移动端做物件的合批处理
F. 构建PVS
G. 构建远景
- 运行时优化层面
- 哪些算法需要双端各有一套:移动端需要合批(PC用模组化+GPU Driven)
- 哪些算法需要双端各有一套参数配置:Streamping配置(加载范围、cell size)
- 哪些资源需要双端各有一套:装饰物(有的只有PC有,有的则是PC具有多样化的物件)
![](https://img.haomeiwen.com/i19200103/d28da33219e1caa5.png)
从上图可以看到,针对某一类固定资产,有些数据是可以跨平台复用的,有些则是不能,如果我们希望生产管线能够自动适配多个不同平台,就要将不能复用的数据拆出来,这对引擎改造来说是一项大工程。
此外,针对不同的资产类型,处理的方式也是完全不同的,从而进一步加剧了这个问题。
展开来说:
1.针对同一套材质,需要考虑如何输出不同平台的两套shader,而且,这里还需要考虑不同渲染管线的区别
2.Mesh的LOD虽然在复用的处理上比较简单,但是FPS游戏希望在多端上的碰撞表现是一致的
3.贴图的分辨率以及压缩设置也需要做不同的处理(这个看起来相对简单)
4.还需要将当前平台不用的数据从cook列表中剔除出去
![](https://img.haomeiwen.com/i19200103/fbd4d4aceca85829.png)
在管线的选择上:
1.PC+高端移动机型,采用的是延迟渲染管线
2.中低端移动机型,采用的是前向渲染管线
为了通过同一套材质来应对上述设备、管线的差异,DFM提出了一种叫做Virtual Material System的东西,这个东西有如下特性(看起来更像是一个大杂烩,而非一套从最初就完整设计好的系统,应该也是初次使用):
1.将资源与shading解耦
2.支持对资源的自定义组织,比如贴图通道的remapping
3.支持对不同平台、不同quality level的配置(相当于性能的分级)
4.提供了一套模块化的材质函数模块以实现材质逻辑的复用
在编辑器模式下,美术跟TA同学会为对应的资源(模型)配置好母材质,并编辑对应quality level的效果,在cook的时候,会将这个材质烘焙成不同的材质实例,并完成这个材质实例与资源的关联。
![](https://img.haomeiwen.com/i19200103/8e75183f4799a26c.png)
下面看看这个系统是如何工作的,系统组织逻辑如下图所示:
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实现
![](https://img.haomeiwen.com/i19200103/056e02e0c2805709.png)
下面来看下,针对不同平台上,怎么做到同样的碰撞表现。
DFM中将模型分为6级LOD,其中PC会使用完全的6级(?),而移动端则只使用后面3级。
可以看到,移动端上的Mesh LOD Bias为3,因此mesh的精度相对于PC会有所下降,因此部分细节会丢失,如下图所示,图中的围栏从LOD3的时候就会被移除:
1.如果围栏对应的碰撞还在移动端上保留,那玩家的体验就会下降
2.如果碰撞移除,那么跟PC的体验就会不一致
3.如果PC跟移动端的碰撞都移除,就会导致效果上的不真实
![](https://img.haomeiwen.com/i19200103/7606415f6cf8b157.png)
这里采取的解决方案是为不同平台设计不同的碰撞数据,这里没有详细描述解决方案(说是TA的talk中有更多描述,后面有时间可以来补充一下)。这里想到的一个方案是在LOD减面的时候,需要考虑碰撞数据的影响,对于会影响碰撞表现的部分,在减面的时候要予以保留。
这种为不同平台进行数据定制的策略不仅仅用在碰撞上面,对于其他的一些资产如天空盒的贴图与压缩配置、lightmap的相关配置,也是采用同样的策略。
![](https://img.haomeiwen.com/i19200103/2e1a52d652d8cd34.png)
讲完了资产编辑与准备,接下来看看场景的表现与性能,在这里,既需要兼顾场景的丰富度,也需要照顾移动端性能下的加载范围
![](https://img.haomeiwen.com/i19200103/50d9b03e7c6e6819.png)
为了实现上面所述的兼顾,这里的思路是将场景的资源拆分为两个部分:
1.共享层,存储的是各个平台共用的数据
a.出于玩法的统一,对于玩法有影响的数据需要放到这个地方
b.出于保持主体视觉的一致,场景的基本布局相关数据也要放在这里
2.平台层,存储的是各个平台特有的数据:出于性能的兼顾,一些偏表现层的数据则可以考虑放到这里
对于共享的数据,也需要针对平台的不同做一些处理,如下图所示,共享数据会被分为HD & Mobile两类。
为了减少美术同学的工作量,这里的另一个原则是尽量将数据往共享层挪,基于这个原则,通过PCG或者其他自动生成工具输出的数据都会自动被拆分为多个平台的
![](https://img.haomeiwen.com/i19200103/dd488f4ae769c6d1.png)
下面看下不同平台下的效果对比:
![](https://img.haomeiwen.com/i19200103/c4c160faab1eb893.png)
![](https://img.haomeiwen.com/i19200103/901ab119846bbed6.png)
![](https://img.haomeiwen.com/i19200103/6c48551f5e8ca230.png)
![](https://img.haomeiwen.com/i19200103/13afe2707b23eea4.png)
![](https://img.haomeiwen.com/i19200103/d6a4dbfe68adf872.png)
![](https://img.haomeiwen.com/i19200103/ea98816bf8c06745.png)
![](https://img.haomeiwen.com/i19200103/29a8ee1cce380e86.png)
![](https://img.haomeiwen.com/i19200103/58e32802f7293b9a.png)
大型项目的另一个问题,如何实现海量资源的高效管理,包括如何维护资源的规范以避免混乱,如何降低数据的冗余(比如通过对资源的扫描,找出重复的贴图或材质等)以及如何保障资源的正确引用等,常用的策略是提供相应的检查与预警工具
![](https://img.haomeiwen.com/i19200103/2b1abe557906e0d8.png)
针对不同平台,在运行时的Streaming配置也需要做不同的处理:
1.为不同平台、不同资源类型设置不同的加载距离
2.对于开镜时的处理也会有所不同,PC是全加载,在开镜的时候切换可见性;移动端则是在开镜的瞬间加载在Frustum内部的数据(性能?)
![](https://img.haomeiwen.com/i19200103/8f3abf2d4405bc2f.png)
接下来看看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
![](https://img.haomeiwen.com/i19200103/fa85f5c56e599c75.png)
如下图所示,上述过程中的部分优化是集成在自动构建环节中的:
![](https://img.haomeiwen.com/i19200103/5b514a2b156ec8ae.png)
其中针对移动端,还做了静态合批以减少Drawcall:
1.先对需要合批的模型进行合并前的确认,包括材质、贴图等是否符合合并规则
2.之后确认合并后的数据的有效性,比如顶点数是否超上限、贴图是否超出最大分辨率以及距离是否合理(指的是待合并的模型之间的距离?)
静态合并的好处是可以保证数据有较好的局部性,同时提升渲染时的性能
![](https://img.haomeiwen.com/i19200103/60c6cad4f2d33659.png)
接下来看看DFM在渲染上的一些策略、如何在多端上实现统一的gameplay效果以及常用的一些性能工具:
![](https://img.haomeiwen.com/i19200103/c9307874d6405f49.png)
虽然不同平台的渲染管线是不同的,但是项目组希望不同平台都具有相同或者相似的主要特性,下面给了两条管线的框架(如果想要复刻这套思路,我们也应该有一张自己的图,图中甚至需要给出不同级别的设备的差异):
![](https://img.haomeiwen.com/i19200103/e8e6429d866fe9d5.png)
先看光照部分,为了实现统一的光照效果,对于主要的特性而言,在不同平台上的实现方式会有所不同,比如sky occlusion是多端共享的,但是AO的实现策略却有所不同,移动端走烘焙,PC则使用的是GTAO以及DFAO(距离场),基于这种一致性设计,美术同学就不需要为场景做两套设计,可以大大提高工作效率
![](https://img.haomeiwen.com/i19200103/2c3e068353a975ea.png)
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数据传输时的卡顿,这里也做了异步处理
![](https://img.haomeiwen.com/i19200103/33e6e8fae0bc3cec.png)
有了动态GI,很自然的就可以添加TOD效果,DFM的TOD是通过sequencer驱动的,多平台共用的参数存储在基础sequencer中,跟平台相关的额外参数则存储在另一个单独的sequencer中:
![](https://img.haomeiwen.com/i19200103/f200d49d8a4d9287.png)
地形的方案是优先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?)
![](https://img.haomeiwen.com/i19200103/627e1d107543253e.png)
关于地形的渲染细节,在Unreal Fest 2023中有更多分享
![](https://img.haomeiwen.com/i19200103/cb4e663f9303ebad.png)
接下来看下Gameplay一致性如何保障,这里将整体的gameplay逻辑分为三层:
1.Core feature layer:对应的是所有平台都一直的一些基础特性,比如Gameplay框架、网络模型、移动同步、武器射击以及其他的一些战斗细节。
2.Flexible feature layer:负责提供一些可以在不同平台上做伸缩控制的特性,这些特性可以基于设备的性能、quality level等来进行参数的动态调控与特性的开关
3.Platform feature layer:用于实现平台不同的特性,比如input/HUD等
![](https://img.haomeiwen.com/i19200103/108989dbeb6692e0.png)
关于角色动画的跨平台设计包括:
1.各平台使用同一套basic skeleton,只是PC上会增加一些额外的骨骼与动态信息
2.动画数据基于同一个角色的parent skeleton创建,因此可以在双端进行复用
a.PC上会采用更高的帧率与效果更好的压缩方式
![](https://img.haomeiwen.com/i19200103/950a822be7b0674f.png)
大部分的动画特性都是双端共享的,只在部分特性上做了处理,对于这些做了处理的特性,有一些也会提供一些开关允许在高端设备上开启,比如换弹动画,在PC上是完整的动作片段,而在移动端上则是通过IK来模拟的,虽然看起来差不多:
![](https://img.haomeiwen.com/i19200103/eb49fafb60fca389.png)
DFM还设计了一套规划算法,来基于每台设备的性能表现与预算,动态决定哪些特性是否需要开启,总的来说,这套算法的思路跟knapsack算法类似,会需要先为每个feature指定一个权重,之后会基于feature开启后的性能消耗来对所有feature进行评估权衡,以获得最高性价比
![](https://img.haomeiwen.com/i19200103/97ac5aff292de4db.png)
这里还给了两个演示视频来展示这个算法的效果
![](https://img.haomeiwen.com/i19200103/7befbabe0ee242eb.png)
DFM还设计了一套自适应的UI框架,大部分的UI数据都是包含在这个框架里的。
为了提升跨平台共用的效率,这里会将平台相关的参数抽取到framework layer(?):
1.DPI会跟屏幕分辨率有关,因此需要为不同平台做专属设计,Display Ratio、Padding也有同样的问题
2.不同平台的UI导航方式(?)会不一样,这部分会需要放在navigation layer中
![](https://img.haomeiwen.com/i19200103/0a27841aed41d3aa.png)
DFM的目标分辨率设定是2k:
1.UI资源的原始尺寸是2k的话,在移动端上会被cook成1080P的
2.PC跟Mobile共享的资源,在PC平台会在运行时被DPI下采样为原始资源的2/3,但是会达到跟4k一样的效果(?)
3.在PC上,建议打开mipmap来避免像素的mismatch
![](https://img.haomeiwen.com/i19200103/0248201707aaf283.png)
最后看看性能工具,DFM对工具诉求是:
1.支持跨平台使用
2.不需要pre-instrumentation(代码预埋)
3.支持长时间的、可扩展的数据搜集
4.不会对运行时性能产生影响
最终自己开发了一套:
![](https://img.haomeiwen.com/i19200103/157ec7e3ced49a1c.png)
工具的逻辑可以分为三层:
1.通过一套跨平台可调用的接口实现高性能的数据采样,这个采样会结合每帧的时间消耗与自定义的数据,统计出每一帧的性能数据
2.对每个函数的性能数据与函数的堆栈进行分析,得到一帧的call tree
3.通过一个服务+既定的规则来对所有数据进行分析,这里会进行一系列的自动化分析,比如Pearson correlation coefficient(皮尔逊相关系数分析),基于这个可以统计出函数之间的关联关系
![](https://img.haomeiwen.com/i19200103/93eb8615766f2623.png)
![](https://img.haomeiwen.com/i19200103/95ca8fa93cf24e91.png)
![](https://img.haomeiwen.com/i19200103/ad516c7865ae0d2a.png)
网友评论