《鸣潮》UE4多平台效果与性能优化实践
[UFSH2023]《鸣潮》基于虚幻引擎4的多平台效果和性能优化实践 | 王宏波 库洛游戏
TAAU 方案解析
0. 背景与核心挑战
-
项目类型: 开放世界、二次元(NPR)、ACT战斗、怪物收集。
-
核心挑战:
-
多平台适配: 需兼顾高画质PC端和性能受限的移动端。
-
二次元特性: 大量高频边缘(勾边、风格化草/树),对抗锯齿要求极高。
-
动态光源: 同屏动态光源极多(200+,夜晚更多),远超常规手游。
-
1. 渲染管线选择:为何坚持 Deferred (延迟渲染)?
在移动端,通常因带宽限制首选 Forward 或 Forward+,但《鸣潮》选择了 Deferred Rendering。
-
决策依据:
-
光源数量: 需支持同屏数百个动态光源,Deferred 在多光源下性能更优。
-
效果追求: 需要在手机上实现高级效果,如 SSR (屏幕空间反射) 和 GTAO (地面实况环境光遮蔽),Deferred 的 G-Buffer 提供了必要数据。
-
开发成本: 对团队而言,Deferred 与 Forward+ 的开发成本差异不大。
-
-
代价: 无法使用 MSAA,必须依赖后处理抗锯齿(Post-Process AA),这给二次元画面的边缘处理带来了巨大挑战。
2. 二次元游戏的抗锯齿挑战
-
边缘像素占比高:
-
写实 PBR 游戏:同屏边缘像素占比约 1% - 2%。
-
二次元 NPR 游戏:由于勾边(Outline)和风格化植被,边缘占比高达 4% - 5% 甚至更多。
-
-
现象: 锯齿(Aliasing)和高光闪烁(Flickering)比写实游戏更严重,普通的 TAA 容易糊或闪。
3. TAA (时间性抗锯齿) 深度优化
《鸣潮》采用了一套混合定制的 TAA 方案,核心在于平衡鬼影(Ghosting)与闪烁(Flickering)。
3.1 渲染流程调整
-
位置后移: 将 TAA Pass 从默认位置移到了 Bloom 和 ToneMapping 之后。
- 注:虽然 Bloom 可能会放大闪烁,但综合考虑后仍选择此顺序(因为性能原因)。
-
定制 Velocity Pass: 增加了专门的 Velocity Buffer (速度缓冲) 用于计算动态物体的历史回溯。
3.2 鬼影优化 (Ghosting)
核心是历史像素混合(History Clamping)的精度与性能权衡。
-
采样优化 (Mobile):
-
PC端通常用 9点采样。
-
移动端优化为 十字星 5点采样 (5-tap cross),节省带宽。
-
-
包围盒 (Clamping Box):
- 移动端选择最廉价的 AABB (轴对齐包围盒) 来限制历史像素颜色范围。
-
颜色空间选择:
-
YCoCg 空间: 高配机型使用,利用亮度(Y)做 Clamp 更符合人眼感知,效果更好。
-
RGB 空间: 低配机型使用,省去色彩空间转换开销,降低 5-tap 采样的带宽压力。
-
3.3 角色勾边的特殊难题 (The "Outline" Problem)
这是二次元游戏特有的性能痛点。
-
问题根源:
-
为了消除角色运动时的鬼影,需要精确的 Velocity Buffer。
-
但渲染角色的代价极高(Base Pass x2, Velocity x2, Shadow, Skinning x2等)。
-
性能妥协: 为了省性能,移动端去掉了角色勾边(Outline)的 Velocity 渲染。
-
-
引发新问题: 勾边没有速度信息,无法正确回溯历史帧,导致严重的边缘闪烁(头发、服饰边缘)。
-
解决方案 (混合策略):
-
低通滤波 (Low-Pass Filter): 对判定为闪烁的边缘区域进行简单的模糊处理(利用已有的 5-tap 采样数据),压制闪烁。
-
动静分离权重: 引入两套权重系统。
-
速度越快 当前帧权重越高(减少鬼影,但可能增加闪烁)。
-
速度越慢 历史帧权重越高(画面更稳定)。
-
-
动态锐化: 针对被 TAA 模糊的动态物体,使用 Unsharp Mask 进行局部锐化(同样复用 5-tap 数据)。
-
4. TAAU (时间性超级分辨率)
在 TAA 基础上实现的 Upscaling(上采样)方案。
-
算法实现:
-
基础:基于目标像素到源像素距离的权重插值。
-
进阶:实现了类似 FSR 1.0 的多项式逼近(Polynomial Approximation)算法,考虑边缘信息,效果优于简单双线性。
-
-
分级策略: 低配用简单的双线性或基础 TAAU,高配开启更复杂的边缘重建算法。
5. 性能参考数据
测试机型:骁龙 865
-
仅开启 TAA: ~1.1 ms
-
开启 TAAU (Upscaling): ~1.5 ms
总结核心思路: 《鸣潮》的图形优化是在追求“主机级特性”(Deferred管线、复杂TAA)和“移动端限制”之间做极致的工程权衡(Trade-off)。例如,为了性能放弃了完美的 Velocity Buffer,再通过后处理算法(低通滤波、动态权重)去弥补由此产生的画质缺陷。
One Pass Deferred 管线避坑指南
0. One Pass Deferred 管线概述
-
核心目标: 将所有主要的渲染Pass合并到一个 Render Pass 中,利用移动端 GPU 的 On-Chip Memory (片上内存),减少对系统内存的读写带宽消耗。
-
基础实现:
-
API 支持: OpenGL ES 3.2, Vulkan, Metal 2/3。
-
G-Buffer 布局 (初始版): 3张 G-Buffer (RGBA8) + 1张 SceneColor + 1张 DepthBuffer。共计4张RT + 1张Depth。
-
材质分类: 卡通角色(NPR)、风格化植被(NPR)、PBR场景。通过 Stencil Mask 区分。
-
深度获取: 依赖
Depth Fetch(从深度缓冲读取深度信息)。
-
1. 巨坑一:ARM Mali GPU 上 Depth Fetch 导致 LPK 失效
这是移动端延迟渲染最常见且最严重的性能陷阱之一。
-
现象:
-
在高通骁龙和苹果设备上性能正常。
-
在 ARM Mali GPU 上,三个 Lighting Pass 的 GPU 指令周期极高,性能骤降。
-
-
原因分析 (Streamline 分析):
-
LPK (Late-Z Pass Kill) 失效: Mali GPU 的一种重要优化机制,用于提前剔除被遮挡的像素。
-
罪魁祸首:
Depth Fetch。在 Mali GPU 上,任何形式的深度纹理采样(无论在 One Pass 还是其他 Pass 中)都会导致当前 Pass 的 LPK 优化彻底失效。
-
-
数据对比:
-
关闭 Depth Fetch: LPK 剔除像素量 ~1.2 M/帧。
-
开启 Depth Fetch: LPK 剔除像素量 ~0.01 M/帧 (几乎为零,性能暴跌100多倍)。
-
注:ARM 表示最新的 Immortalis-G720 可能已在驱动层面解决此问题,但旧设备仍受影响。
-
1.1 解决方案:混合管线重构 (Hybrid Pipeline)
为了在 Mali 上保持高性能且不降低画质,团队选择了艰难的重构之路。
-
核心冲突:
-
必须放弃
Depth Fetch以恢复 LPK。 -
放弃
Depth Fetch意味着必须把深度信息存入 G-Buffer。 -
PLS (Pixel Local Storage) 限制: 移动端片上内存通常只有 128-bit (尽管文档可能写更高,实际可用往往受限)。原有的 G-Buffer 布局已经占满,无法再塞入深度信息。
-
-
最终方案: One Pass Deferred + Forward (Hybrid)
-
角色改为 Forward 渲染: 将最复杂的卡通角色从 Deferred 管线中剥离,走前向渲染。
-
G-Buffer 重编码:
-
因为角色移出,G-Buffer 不再需要存储角色特有的数据。
-
利用腾出的空间,将 线性深度 (Linear Depth) 编码进 G-Buffer。
-
-
Pass 结构调整:
-
初版尝试失败: 若将角色 Forward Pass 放在透明物体渲染之后,会导致排序错误、效果缺失(水体、雾效等),且打断 One Pass,增加带宽。
-
最终成功架构: 将角色 Forward Pass 紧接在 Lighting Pass 之后,在同一 Render Pass 内完成。这样只需额外处理 Decal 和 Light Function,而水体、雾等可在后续统一处理。
-
-
-
优化成果 (Mali GPU):
-
平均温度下降 5-6°C。
-
GPU 时钟频率下降约 25%。
-
2. 小坑二:UE4 引擎 Bug 导致带宽节省不达预期
这个问题隐藏较深,主要影响高通 Adreno GPU。
-
现象:
-
理论上 One Pass 应该大幅节省读写带宽。
-
实际上,读带宽 (Read Bandwidth) 节省明显,但 写带宽 (Write Bandwidth) 几乎没有变化。
-
-
原因分析:
-
UE 4.26/4.27 RHI Bug: 引擎底层的
Render Hardware Interface实现有缺陷。 -
在结束 Render Pass 时,应该 Discard (丢弃) 掉中间计算用的 G-Buffer,不写回系统内存。
-
但有 Bug 的代码仅对 SceneColor 和 Depth 生效,而忽略了 G-Buffer RT A/B/C,导致它们仍然被强制写回了内存,浪费了大量带宽。
-
注:UE5 已修复此问题。
-
-
修复: 修改引擎底层代码,确保所有中间 RT 都能被正确 Discard。
3. 带宽优化最终数据
-
测试结果 (60fps):
-
理论预期节省: ~1.8 GB/s
-
实际节省: ~830 MB/s
-
-
原因: 现代移动 GPU (Adreno/Mali) 都有非常高效的 AFBC (ARM Frame Buffer Compression) 或类似技术,本身的带宽压缩效率已经很高,因此 One Pass 带来的额外收益比理论值小。
-
各平台表现:
-
读带宽节省: > 30%
-
写带宽节省: 10% - 15%
-
-
最终带宽消耗: 约 1.2GB/s - 1.4GB/s (对于 60fps 的高画质游戏来说非常优秀)。
总结核心思路: 移动端 Deferred 管线的成功关键在于对硬件特性的极致利用与规避。必须了解 Mali 的 LPK 机制和 PLS 大小限制,同时要敢于修改引擎底层 RHI 以修复阻碍优化的 Bug。混合管线(Hybrid Pipeline)是平衡复杂材质需求与硬件限制的有效策略。
多平台植被渲染方案
0. 多平台适配策略
《鸣潮》采用了一种统一化的多平台适配框架,将不同平台视为同一连续谱系上的不同配置点。
-
核心理念:
-
PC高配 PS5
-
PC中配 PC低配 PS4 移动端高配
-
影响因素: 计算能力 (CPU/GPU)、内存、IO性能、功耗、包体大小。
-
-
适配阶段:
-
打包时: 区分平台资源,烘焙特定数据(如Shader变体、纹理格式)。
-
加载时: 按需加载,过滤掉非当前平台所需的数据。
-
运行时: 动态调整画质参数(如LOD距离、分辨率缩放)。
-
-
重要提示 (坑):
-
Gameplay数据必须与渲染数据分离: 碰撞、寻路、物理等数据不能随画质LOD变化,否则会导致角色陷地、穿墙等严重Bug。
-
优势: 作为ACT游戏,只需关注角色周围30-50米的Gameplay精度,远距离物理精度要求低(对比FPS游戏)。
-
1. 植被渲染方案总览
针对开放世界大规模森林,采用了分级的渲染策略。
| 平台 | 近景 (Close) | 中景 (Middle) | 远景 (Far) |
|---|---|---|---|
| PC / 主机 | 模型树 (Mesh Tree) | Billboard树 | Imposter树 |
| 移动端 | Billboard树 | Imposter树 | Imposter树 |
2. Billboard 树 (广告牌树)
作为移动端近景和PC中景的主力方案,旨在替代传统的插片树模型。
这里的Billboard 树指的是RTR4 13.6.5小节 Billboard Representation提到的Billboard Cloud方法。
-
实现原理: 将原本复杂的插片树叶,替换为多层面朝相机的 Billboard 面片。
-
优势:
-
面数大幅降低: 仅需原模型树面数的 30% - 40%。
-
效果还原度高: 在视觉上能基本还原插片树的体积感和光影。
-
-
缺陷与解决:
-
问题: 阴影会随相机转动而错误旋转(因为Billboard面朝相机)。
-
解决: 渲染阴影时,让 Billboard 面朝光源,而非相机。
-
3. Imposter 树 (基于图像的代理树)
用于极远景的高效渲染方案。
-
核心概念: 并非简单的Billboard。是在离线阶段,围绕树木从多个角度拍摄一系列“快照”,存储其渲染信息。运行时根据相机视角,选取最接近的快照进行合成渲染。
-
设计目标:
-
还原着色与形态。
-
全功能投影支持: 自身投影、接受场景投影、云层投影。
-
极低的内存与Draw Call占用。
-
-
G-Buffer 设计 (32-bit Texture):
-
RG: 法线 (Normal) 信息。
-
B: 局部深度偏移 (Local Depth Offset)。
-
A: Diffuse灰度 + 材质标记 (区分树叶/树干,用于不同着色处理)。
-
-
深度还原技术 (核心):
-
利用存储的
Local Depth Offset和 Billboard 在相机空间的位置,重建出近似原始模型的深度信息。 -
有了准确深度,就能完美支持各类阴影技术 (Shadow Map, AO, 雾效等),与普通模型无异。
-
-
内存优化:
-
动态 Texture Array: 扩展UE默认机制,支持按需流式加载 (Streaming) Imposter 切片,大幅降低显存占用。
-
数据: 3000+ 棵树实例 (50种类型),仅占用 < 15MB 内存。
-
-
性能表现:
-
1000+ 棵可视树木,仅需 4个 Draw Call。
-
总面数 < 4万。
-
GPU耗时极低。
-
4. 其他工程优化
-
LOD 集成: Billboard 和 Imposter 直接嵌入树木的 LOD 链中,引擎自动处理切换。
-
ISM (Instanced Static Mesh) 优化: 针对使用 ISM 的近景树木,选取 Chunk 中最大的物体来计算 LOD 切换距离,解决 ISM 包围盒过大导致 LOD 切换迟钝的问题。
总结核心思路: 《鸣潮》通过定制化的 Billboard 和 Imposter 技术,成功在移动端实现了大规模植被的低成本渲染,同时保持了动态光影(特别是阴影)的完整性,是其能够在移动端呈现开放世界大场景的关键技术之一。