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),尤其是 Switch 和 PlayStation,而非 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 Scans 或 FAB)时。

什么是 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 Component 的 Ray 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有固定开销,轻量场景可能不划算,但高多边形场景收益巨大,务必实测