UE5 Graphics Deep Insights From Japan

UE5 Graphics Deep Insights From Japan | Unreal Fest Bali 2025

虚幻引擎在日本市场的应用概览

主要游戏作品

  • 多款主机大作使用虚幻引擎开发:《最终幻想7》《王国之心》《皇牌空战》《皮克敏》《Hi-Fi Rush》
  • 虚幻引擎不仅适用于 照片级写实(Photorealistic) 风格,也广泛用于 非照片级写实(Non-Photorealistic / NPR) 风格,例如 《女神异闻录》 系列

游戏之外的应用场景

  • 动画制作:日本热门动画(如"Pikua")使用虚幻引擎制作包含全角色动画的片尾影像,相关工作流已发布博客(基于 UE4)
  • 漫画创作:利用虚幻引擎决定漫画分镜布局,渲染背景图像后再进行手工修饰
  • VTuber 与虚拟演出:VTuber 在日本已成为主流文化,线下演唱会可吸引数万名观众,这些演出充分利用了虚幻引擎灵活强大的实时渲染能力

日本市场的独特特征

  • 风格化图形(Stylized Graphics) 深受偏爱,受漫画和动画文化影响深远
  • 主要 3D 游戏平台为 主机(Console),尤其是 SwitchPlayStation,而非 PC 或移动端
  • 因此对 严格的性能优化 有极高要求

GPU 性能分析(GPU Profiling)

核心问题:ProfileGPU 的测量结果到底有多准确?

这是本节的核心议题。ProfileGPU 是日常开发中最常用的 GPU 性能分析命令之一,无论在编辑器中还是在运行时/主机上都广泛使用。但其测量精度与 异步计算(Async Compute) 的支持状况密切相关。

UE5 中异步计算的演进

UE5 越来越多地使用 异步计算(Async Compute) 来提升 GPU 性能和效率。核心思路是让渲染相关的处理在 图形管线(Graphics Pipe)计算管线(Compute Pipe) 之间 异步并行 执行,从而更充分地利用 GPU 资源。

UE 5.5 及更早版本的局限

  • Unreal Insights 无法显示异步计算管线的活动
    • 例如 Lumen Screen Probe(Lumen 的关键处理步骤)在 Insights 中完全不可见
    • 只有 手动关闭 Lumen 的 Async Compute 后,这些 Pass 才会出现在 Insights 中
  • ProfileGPU 在测量时会禁用异步计算
    • 这意味着测量结果 没有包含异步计算带来的性能收益
    • 因此 测量结果不准确,无法反映真实的 GPU 工作负载

UE 5.6 的改进

  • Unreal Insights 现已支持可视化 Compute Pipe,无需额外设置即可看到异步计算活动
  • ProfileGPU 也开始支持 Async Compute,能同时显示 Compute Pipe 和 Graphics Pipe
  • 注意:编辑器中的 ProfileGPU 专用 UI 窗口在 5.6 中被移除,结果仅输出到 Output Log

UE 5.7 的进一步变化

  • ProfileGPU 的 UI 窗口 重新恢复
  • 重要区别:5.7 版本的 ProfileGPU 不会禁用异步计算,因此提供的是 更准确的性能开销百分比测量
  • 局限性:虽然测量更准确,但它 不显示 Compute Pipe 的具体活动内容
  • 如果需要看到完整的异步计算全貌,应使用 Unreal Insights

异步计算给性能分析带来的挑战

由于异步计算的引入,许多处理过程现在互相重叠(Overlap),这使得 孤立地观察单个 Pass 的 GPU 工作负载变得更加困难

具体示例

  • 在 Insights 的时间线图中,Lumen Scene Lighting 看起来可能只花费约 2 毫秒
  • 但实际上,其内部包含许多 GPU 处于等待状态(Waiting/Idle) 的片段
  • 表面上的时间跨度并不等于真正的计算负载

实用建议

  • 如果需要 精细调优和优化某个具体的渲染 Pass,可以 临时禁用该 Pass 的异步计算,使其以同步方式运行,从而获得更清晰的单独性能数据
  • 讲者还展示了 Lumen 中多个异步处理相关的控制台变量(CVar),可按需逐个禁用

是否还需要平台级 GPU Profiler?

答案是:绝对需要。

Unreal 内置工具的定位

工具优势局限
ProfileGPU快速定位性能瓶颈所在无法解释"为什么"某个 Pass 开销大
Unreal Insights轻量级、可视化异步计算全貌、适合日常分析同样无法深入到硬件级别的原因分析

平台/硬件厂商提供的 Profiler

  • 包括 PIX(Xbox/Windows)、Razor(PlayStation)、以及各 GPU 厂商的专用工具
  • 通过 帧捕获(Frame Capture),可以快速判断某个 Pass 的开销来源:
    • 计算量过大(Heavy Computation)
    • 纹理访问过多(Excessive Texture Access)
    • 寄存器使用量过高(High Register Usage / Register Pressure)
    • 与异步计算的重叠方式不当
  • 使用平台级 Profiler 可以 避免在无效或方向错误的优化上浪费时间

本节核心总结

  1. 由于 异步计算的广泛采用,理解单个 Pass 的真实 GPU 负载变得更加困难
  2. UE 5.6 开始,Unreal 的各种内置工具已支持 异步计算的可视化
  3. 若需精确观察单个 Pass 的处理负载,应 临时禁用对应的异步计算
  4. Unreal Insights 是轻量级首选的日常分析工具
  5. 要深入理解 "为什么某个 Pass 开销大",必须使用 硬件厂商提供的 GPU Profiler

Shader Complexity 视图模式的误区与正确用法

基本原理

  • Shader Complexity 视图模式 用于可视化每个像素执行的 着色器指令总数
  • 一位日本用户曾在社交媒体上开玩笑称要成立 "Shader Complexity 视图消灭委员会",这背后有深层原因

可视化机制

  • 不透明(Opaque)区域:在默认渲染器中,每个像素 只计算一次
  • 半透明(Translucent)渲染叠加式(Additive) 的:半透明层越多重叠,每像素的开销就越高
  • Shader Complexity 视图的 适用场景
    • 快速识别 不透明着色器指令数过高 的区域
    • 发现 多层半透明绘制重叠 的区域
    • 或两者兼有的情况

查看实际着色器指令数

  • 材质编辑器(Material Editor) 中有一个 Platform Stats 窗口
  • 可以根据具体的材质设置,查看 各平台对应的着色器指令数

核心洞察:指令数 ≠ 性能开销

这是本节最重要的结论。

生动类比

  • 就像小孩说"爸爸做个煎饼"和"在大会上做两场演讲"——两句话写出来都只是一行文字,但 实际工作量完全不同
  • 着色器指令也是一样:有些指令涉及 纯计算,有些涉及 纹理采样(Texture Access),两者的 实际性能开销差异巨大

GPU 编译器的智能优化

  • 现代 GPU 着色器编译器非常聪明
  • Alpha Test(透明度测试) 为例:当着色器包含 discard 指令时,编译器可能会 优先计算 Alpha 条件,只有当像素不被丢弃时才继续执行后续计算
  • 这意味着实际执行的工作量可能远小于指令总数所暗示的

极端反例演示

示例指令数实际 GPU 开销说明
恶意材质设置(球体)39 条指令20 毫秒低指令数,极高开销
刻意增加指令2533 条指令0.04 毫秒高指令数,几乎无开销

这充分证明:指令数与性能开销之间没有直接的线性关系

Shader Complexity 视图的另一大缺陷:Masked Material 的误导

  • 使用 遮罩材质(Masked Material) 制作的树叶形状,透明区域实际上 仍然在运行着色器并执行 Alpha 测试
  • 但这部分开销 完全没有反映 在 Shader Complexity 视图中
  • 结果是:遮罩材质被可视化为 完全不透明材质 的样子,造成 严重误导
  • 这很可能就是那位日本用户发推吐槽的原因

推荐用法与优化建议

  • Shader Complexity 视图的最佳用途:仅用于检查 半透明元素的重叠情况
  • 正确的材质优化方法:使用 详细的 GPU Profiler(如 Unreal Insights 或 ProfileGPU)来精确定位 真实的性能瓶颈
  • 最危险的做法:仅因为 Shader Complexity 视图显示为红色或白色,就花大量时间 削减指令数——这可能是 无效优化,既浪费时间又可能牺牲画面质量

TSR(Temporal Super Resolution,时域超分辨率)

4K 原生渲染的性能压力

  • City Sample 场景为例,4K 原生渲染在某 GPU 上耗时约 57 毫秒(低于 20 FPS)
  • 随着场景物体增多、渲染技术日趋复杂,4K 分辨率渲染依然 非常昂贵

TSR 的基本工作原理

  • TSR 是 UE 内置的 时域上采样方法
  • 在渲染管线中,TSR 位于 景深(Depth of Field)之后,将较低的内部分辨率 上采样到目标分辨率
  • 效果对比:1080p 经 TSR 上采样后与 4K 原生渲染之间 几乎看不出差异
  • 性能收益:从 57 毫秒降至约 16 毫秒(示例数据),因为 Nanite 和 Lumen 都依赖内部分辨率,所以 TSR 也大幅降低了它们的负载

TSR 的关键机制:多帧采样

TSR 通过 参考过去多帧的数据 来实现上采样,这带来了几个需要注意的问题:

内部分辨率与帧率的影响

  • 输出分辨率 = 目标分辨率 时:无需额外操作,直接使用即可
  • 内部分辨率降低 时:TSR 需要 参考过去的帧 来补充信息以达到高分辨率
  • 内部分辨率进一步降低 时:需要参考 更久远的帧
  • 帧率影响:在 30 FPS 下需要的采样帧数与 60 FPS 相同,但这意味着 TSR 需要参考 时间上两倍久远的帧

鬼影问题(Ghosting)

  • 根本原因:当分辨率过低或帧率过慢时,TSR 需要参考 非常古老的帧,导致全屏出现 鬼影/拖影
  • 极端示例:仅以 25% 内部分辨率 渲染时:
    • 摄像机移动 时:整个画面 非常模糊
    • 摄像机静止 时:TSR 能逐渐生成 越来越高分辨率 的清晰画面——这是 TSR 在静态场景下的强大优势

重要警告:CPU 导致的掉帧也会影响 TSR

  • 即使 GPU / 渲染开销很低,CPU 端的动画、加载等操作导致 FPS 下降,同样会在 TSR 中产生鬼影
  • 这种 CPU 端的开销 无法通过动态分辨率或任何 GPU 技术来缓解
  • 要维持 TSR 质量,必须保持 CPU 和 GPU 性能都稳定

TSR 与速度向量(Velocity Vector)

  • TSR 使用 速度向量(Velocity) 来估算帧间的变化
  • 如果速度向量 未正确写入,TSR 将无法正确工作
  • 错误示例:物体在旋转,但速度向量未变化 → 物体上出现 严重模糊/鬼影
  • 修正后:生成正确的速度向量后,鬼影 完全消失

TSR 文档资源

  • UE 5.4 开始,TSR 的官方文档已经 大幅扩充,详尽到可以出版成一本书
  • TSR 是 平衡画质与性能的关键功能,强烈建议仔细阅读官方文档

TSR 要点总结

因素影响
低内部分辨率 / 低帧率需要更多时间积累样本来生成高分辨率图像,导致严重鬼影
速度向量不正确在对应区域产生鬼影和模糊
CPU 掉帧同样会触发鬼影,且无法用 GPU 技术解决
静态场景TSR 表现极佳,即使极低分辨率也能逐帧收敛到高画质

Megalights(巨量光源)

功能定位

  • Megalights 是一项 正在开发中的激动人心的新特性
  • 设计目标:即使在 主机平台 上也能高效支持 大量光源

核心原理:固定采样预算

  • Megalights 之所以能支持大量光源,是因为 每像素每帧的最大采样数是固定的
  • 这意味着即使光源数量增加,处理开销也不会显著增长

与传统方法的对比

方面传统光照渲染Megalights
计算方式为每个光源逐一进行光照计算,确保精确且物理正确固定采样预算,智能分配给最重要的光源
性能随光源数量的变化线性增长——每增加一个光源,开销就增加基本不变——光源数量增加,开销保持稳定
设计理念优先 渲染精度,牺牲性能优先 性能稳定,可能引入微小误差
潜在问题光源过多时性能急剧下降可能出现 微小的误差或可见瑕疵(Artifacts)

重要警告:仍为实验性功能

  • Megalights 当前仍处于 实验性(Experimental) 阶段
  • 尽管它令人兴奋且功能强大,许多开发者跃跃欲试
  • 强烈建议不要在正式生产项目中使用 Megalights
  • 目前没有关于何时移除实验性标签的具体时间表

Virtual Texture(虚拟纹理)与 VSSM(虚拟阴影贴图)

Virtual Texture 的注意事项

  • UE 5.6 开始,Virtual Texture 默认开启
  • 关键限制:虚拟纹理的最小尺寸等于其 Tile Size,默认为 128×128
    • 系统 不会生成小于该尺寸的 Mip Map
    • 结果:高频率虚拟纹理在远处可能产生 严重的摩尔纹(Moiré Pattern),画面出现明显瑕疵
  • 缓解方案:TSR 的 Shading Rejection 选项可以极大改善摩尔纹问题
    • Scalability 设为 High 或以上(Epic、Cinematic)时,该选项 默认开启
    • 但这 并非完美解决方案,某些相机角度仍可能出现摩尔纹
    • 目前 没有已知的完美解决方案

VSSM(Virtual Shadow Maps,虚拟阴影贴图)的优化

为何关注 VSSM?

  • 一些开发者 放弃使用 VSSM,原因是:
    • 默认的 Page Pool Size 为 512MB
    • 内存消耗GPU 负载 对其项目来说过高
  • 但实际上,VSSM 的内存和 GPU 负载已有 大幅优化空间

UE 5.4 的重大更新

  • 引入了 动态自动调整 Page LOD 的功能,根据 Pool Size 自动适配
  • 实际效果示例
    • Page Pool Size 从 496MB → 100MB
    • 内存消耗从 512MB → 仅 60MB
    • 阴影仍然渲染良好,因为 Page LOD 自动提升
  • 这是一个 非常强大的系统,但很多人还不知道
  • 关键控制台变量:r.Shadow.Virtual.MaxPagePoolLoadFactor(建议尝试调整)

UE 5.6 的新特性

  • 新增了基于性能 动态降低 VSM 处理负载 的功能,类似于 动态分辨率(Dynamic Resolution) 的思路
  • 可根据实际帧率自动调节 VSM 的工作量

VSSM 总结建议

  • 如果觉得 VSM 内存占用过高,先尝试 减小 Page Pool Size 并配合相关控制台变量
  • UE 5.4 及以上版本 的自动 LOD 调整非常值得启用

Lumen 的实际使用陷阱

Lumen 的优势

  • 实现 无需烘焙的全局光照(GI),支持运行时 动态光照
  • 大幅减少 光照烘焙工作流 的时间成本

Lumen 的已知缺陷

  • 与 TSR 类似,Lumen 依赖时间上累积的信息,可能产生 鬼影(Ghosting)拖尾伪影(Trailing Artifacts)
  • 性能开销较高(虽然持续改进中)

核心问题:模块化资产 vs Lumen Card 的矛盾

这是 Epic Games Japan 在支持日本开发者过程中遇到的 最大问题,尤其是当从外部导入资产(如 Mega ScansFAB)时。

什么是 Lumen Card?

  • Lumen 为了快速计算 GI,会用 极简的平面(Lumen Cards) 包裹每个物体
  • Lumen Card 是 预计算的,对应每个 Static Mesh
  • 即使是复杂形状(如树木),Lumen Card 也只是 简单的盒子形状

问题一:复杂单体网格无法正确生成 Lumen Card

  • 如果将整个房屋内部做成 一个完整的复杂 Mesh,Lumen Card 无法适配其形状
  • 结果:出现 粉色区域,表示 Lumen 无法正确计算着色
  • 基本规则:使用 Lumen 时,复杂形状应由 多个简单模块化资产(Modular Assets)组合而成

问题二:模块化资产导致 Lumen Card 数量爆炸

  • 如果每个模块化组件都有独立的 Lumen Card,一栋建筑可能产生 数量极多的 Lumen Card
  • 处理负载和内存消耗 会急剧飙升,无法实时处理

解决方案:Ray Tracing Group ID 合并 Lumen Card

  • UE 提供了 合并相同 ID 对象的 Lumen Card 的机制
  • 对应属性:Static Mesh ComponentRay Tracing Group ID
  • 相同 ID 的物体,其 Lumen Card 会被合并
  • 无论 Lumen 使用 软件光追还是硬件光追,此机制均有效
  • City Sample 的做法:每栋建筑的所有模块化组件设置 相同的 Ray Tracing Group ID,整栋建筑只有 一个 Lumen Card
  • 效果:大幅减少 Lumen Card 数量,降低处理负载

副作用:室内外无法兼得

  • 合并 Lumen Card 后,简单的盒状 Card 无法正确覆盖建筑内部
  • City Sample 中没有任何建筑可以进入内部,正是这个原因
  • 目前 没有已知的 Lumen 机制可以同时正确处理建筑的外部和内部
  • 实际应对方案
    • 将建筑的 外部和内部分开创建
    • 在游戏逻辑层面 切换内外部的可见性(Visibility)
    • 减少不必要的 Lumen 内部计算

Lumen 总结建议

  • 每个新版本都在持续进行 重大优化和功能改进
  • 如果使用模块化资产构建场景,务必使用 Ray Tracing Group ID 对 Lumen Card 进行分组
  • 可以提升 Lumen 场景质量并降低性能开销
  • 但必须 充分理解其副作用(尤其是室内外问题)

Nanite 的性能评估

核心问题:Nanite 对低多边形/轻量场景是否有效?

测试一:轻量场景(Sol City 示例项目)

  • 将 Sol City 中所有 Mesh 转换为 Nanite
  • 大多数 Mesh 仅约 1,000 多边形
  • 测试条件:启用 Lumen 和 VSSM
配置GPU 时间
Nanite 开启9.9 ms
Nanite 关闭7.85 ms
  • Nanite 关闭时反而 快约 1.4 ms
  • 原因:对于轻量场景,Nanite 的 基础开销(Baseline Overhead)超过了其带来的收益

测试二:高多边形场景(大量树木)

  • 单棵树 Mesh 约 146 万多边形
  • 使用 PCG 放置约 300 棵树
配置GPU 时间
Nanite 开启10.28 ms
Nanite 关闭超过 100 ms
  • Nanite 的 性能优势巨大,接近 10 倍加速

关键发现:Nanite 的性能扩展特性

  • 对比两个测试:从轻量场景到高多边形树木场景,启用 Nanite 时 GPU 时间仅增加了约 1 ms(从 9.9 → 10.28 ms)
  • 这说明 Nanite 的性能影响随多边形数量的增加呈非常平缓的增长
  • 当然,不使用 Nanite 时,可以通过手动创建精细的 LOD 模型 来优化性能,但 Nanite 自动处理这一切 是其巨大优势

Nanite 总结建议

  • Nanite 存在 固定的性能基础开销
  • 在非常轻量的场景中,关闭 Nanite 可能更快
  • 不要草率下结论 说"Nanite 对简单场景太重,直接关掉"
  • 正确做法:仔细测量(Measure)评估你的具体场景,用数据做决策

全文要点回顾

主题核心要点
GPU ProfilingUE 5.6/5.7 改进了 Async Compute 的可视化与测量支持
Shader Complexity指令数 ≠ 性能开销,仅适合检查半透明重叠
TSR多帧累积上采样,注意 Ghosting 与速度缓冲区问题
Virtual Texture5.6 默认开启,注意最小 Mip Map 导致的摩尔纹
VSSM减小 Page Pool Size + 自动 LOD 可大幅降低内存
Lumen模块化资产需用 Ray Tracing Group ID 分组,注意室内外限制
Nanite有固定开销,轻量场景可能不划算,但高多边形场景收益巨大,务必实测