mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
4044 字
12 分钟
UE5 渲染管线 05:Nanite Cluster、双阶段遮挡与虚拟化几何
2026-07-16
NOTE

系列导航:00 总览04 Deferred Frame05 Nanite → 06 Lumen(待写)。版本基线为 UE 5.8;Nanite 对 Skeletal Mesh、Translucency、Ray Tracing 和 Deformation 的支持仍在快速演进,能力矩阵必须以目标分支文档为准。

先给结论#

Nanite 不是“把高模自动生成几级 LOD”,而是一套虚拟化几何系统:

  1. 离线把 Mesh 构建成可分层选择、可流送的 Cluster Hierarchy;
  2. 运行时在 GPU 上按 Instance、Hierarchy Node 与 Cluster 多级剔除;
  3. 按屏幕误差选择足够细、但不过度细的 Cluster;
  4. 用 Hardware Raster 与 Compute Software Raster 协作处理不同屏幕尺度的三角形;
  5. 输出 Depth 与可见表面标识,再执行 Material Classification / Shading;
  6. 只让必要几何 Page 驻留,缺页时继续使用可用的更粗层级而不是直接出现洞。

它主要替换传统渲染器的几何前端。Nanite 之后仍然需要:

  • GBuffer / Material 属性;
  • Direct Lighting;
  • Lumen GI 与 Reflections;
  • Virtual Shadow Maps;
  • Translucency 与 Post Process;
  • TSR、Tonemap 和 Present。

传统 LOD 与 Nanite 的差别#

维度传统 Static Mesh 路径Nanite
细节层级资产作者或工具生成离散 LODBuilder 生成 Cluster 层级与误差
选择粒度通常整个 Mesh Section / LODInstance 内按 Cluster 局部选择
提交有限数量 Mesh Draw CommandGPU 驱动 Cull / Raster Dispatch 与 Bin
几何驻留每个 LOD 作为较大单位几何数据按 Page 虚拟化流送
遮挡Primitive / Instance 为主继续细化到 Node / Cluster
小三角形固定功能 Rasterizer 效率可能下降可转入 Software Raster 路径
材质Base Pass 随 Draw 执行先确定可见表面,再组织 Material 工作
阴影Shadow Pass 重画 Mesh LODVSM 可复用 Nanite Cluster 几何前端

Nanite 仍有 Instance、Material Bin、Raster Bin 和 Dispatch;“GPU Driven”不等于没有提交与调度成本。

离线构建:从三角形到可流送层级#

flowchart LR A["Source Mesh<br/>Triangles / Sections / Attributes"] B["Cluster Partition"] C["Simplify / Group / Error Metric"] D["Cluster Hierarchy / DAG"] E["Root + Streaming Pages"] F["Cooked Nanite Resource / DDC"] A --> B --> C --> D --> E --> F

Cluster#

Cluster 是一小组空间和拓扑上相关的三角形,保存:

  • 压缩后的 Position / Index / Attribute 数据;
  • Bounds 与用于 Cull 的信息;
  • Material Range / Section 关系;
  • 层级与 Streaming Page 引用;
  • 选择细节所需的误差度量。

Cluster 的目标三角形数、编码和 Group 方式是实现细节,不应成为 Gameplay 或工具链的固定假设。

Hierarchy 与 Error#

Builder 对 Cluster 分组并生成更粗表示,形成可从粗到细遍历的层级。运行时根据:

  • 投影尺寸;
  • 层级 Error;
  • 当前 View 的分辨率 / Screen Percentage;
  • Nanite 质量阈值;
  • Streaming Page 是否驻留;

选择一组覆盖原几何且误差足够小的 Cluster。相邻区域可以选择不同层级,因此不是“整个 Mesh 瞬间从 LOD1 跳到 LOD2”。

Root Page 与 Streaming Page#

最基本的粗表示需要保持可用,更细数据按虚拟 Page 流送。运行时遍历遇到缺失细节时:

  • 使用当前已驻留的父层级表示继续渲染;
  • 产生或更新 Streaming Request;
  • Streaming Manager 安排 IO、解压 / 转码与 GPU Page Pool 更新;
  • 后续帧在数据就绪后选择更细 Cluster。

这让“几何超出预算”表现为逐渐降低可见细节,而不是传统资源缺失的整块空洞;但极端 IO / Pool 压力仍会造成细节迟到和请求抖动。

运行时总链路#

flowchart TD S["GPU Scene Nanite Instances"] H["Hierarchy Traversal<br/>Instance / Node / Cluster Cull"] P["Previous HZB"] M["Main Cull + Raster"] D["Main Depth / Visibility"] C["Current HZB"] R["Post Cull + Raster"] V["Final Nanite Visibility / Depth"] B["Raster / Material Classification Bins"] MS["Material Shading"] G["Scene Depth / GBuffer / SceneColor"] F["Streaming Feedback / Requests"] IO["IO / Decompress / GPU Page Pool"] S --> H P --> M H --> M --> D --> C H --> R C --> R D --> V R --> V --> B --> MS --> G H --> F --> IO --> H

GPU Capture 中会看到更多 Init Args、Queue State、Persistent Cull、Safe Args、Patch、Emit Depth、Material Resolve 等子事件。上图只保留数据流主干。

多级 Cull:从 Instance 到 Cluster#

Instance Cull#

Nanite Instance 先经过 View Frustum、Distance、Flags、Primitive / Instance Bounds 等粗粒度测试。如果整个 Instance 不相关,就不遍历它的 Cluster Hierarchy。

Node Cull#

层级节点允许一次拒绝一大片子 Cluster。Node Bounds、遮挡与误差测试决定:

  • 整个节点不可见:停止遍历;
  • 节点可见但当前表示足够细:选择当前 Cluster 表示;
  • 误差过大且子节点驻留:继续细分;
  • 子 Page 未驻留:使用当前可用表示并请求数据。

Cluster Cull#

叶级或被选择的 Cluster 继续接受:

  • Frustum / Clip Plane;
  • Occlusion;
  • Backface / Cone 类保守测试(适用时);
  • 屏幕尺寸 / Pixel Error;
  • Material / Raster 路径支持;
  • View 类型与 Shadow / VSM Page 范围。

Candidate Cluster 很高而 Visible Cluster 很低,可能说明粗层级 Cull、Bounds 或层级结构没有有效拒绝工作。

双阶段遮挡:上一帧 HZB 与当前帧 HZB#

只使用上一帧 HZB,快速移动相机时会把上一帧被挡住、当前刚显露的几何误判;只使用当前 HZB,又必须先有足够 Depth 才能完成判断。Nanite 用 Main / Post 两阶段处理这个环:

sequenceDiagram participant Prev as Previous HZB participant Main as Main Pass participant Depth as Current Depth / HZB participant Post as Post Pass participant Final as Final Visibility Prev->>Main: Cull 历史上可判断的 Cluster Main->>Depth: Raster 可见结果并建立当前遮挡基础 Depth->>Post: 用当前 HZB 重测不确定/历史遮挡候选 Post->>Final: 补画当前新显露的 Cluster Main->>Final: 合并 Main 可见结果

精确 Candidate 分类和 HZB 构建顺序会随分支优化,但稳定目标是:

  • 利用历史遮挡减少大部分工作;
  • 对 Camera Movement / Disocclusion 保持保守正确;
  • 用当前 Depth 补上上一帧无法正确判断的几何。

若只看 Main Pass Cluster 数,会漏掉 Post Pass;性能记录要同时保存两阶段 Candidate / Visible / Raster 数据。

Hardware Raster 与 Software Raster#

为什么小三角形适合 Software Raster#

屏幕上小到接近像素的三角形,会让固定功能 Raster Pipeline 的 Setup、Quad 利用率和三角形吞吐成为瓶颈。Nanite 可以把适合的 Cluster 交给 Compute Software Rasterizer,以线程组方式投影、测试并原子更新可见表面。

较大三角形通常仍适合 Hardware Rasterizer。运行时按投影尺度和 Raster Bin 选择路径:

大三角形 / 常规 Raster 状态 → Hardware Raster
微小三角形 / 高密度 Cluster → Software Raster
两者 → 统一的 Nanite Visibility / Depth 结果

这不是用户手工给每个 Mesh 选择的静态开关;实际阈值和平台实现由 Nanite Renderer 决定。

Programmable Raster#

Masked、Two-Sided、World Position Offset、Pixel Depth Offset 等功能可能需要不同的 Programmable Raster Bin / Shader Permutation。它们能扩展 Nanite 材质表达,但代价包括:

  • 更多 Raster Bin 与 Shader;
  • 更差的 Cluster / Warp 一致性;
  • WPO 后 Bounds 与 Cull 更保守;
  • Masked 覆盖和叶片叠层产生 Overdraw;
  • PSO / Shader 编译与运行时分派增加。

“已支持 Nanite”不代表与纯 Opaque、无变形 Nanite 的成本相同。

Visibility Buffer 与 Material Shading#

Nanite 几何阶段先决定每个像素最终可见的 Cluster / Triangle,并写入可恢复表面信息的 Visibility 结果与 Depth。随后 Renderer:

  1. 对可见像素按 Material / Shading 路径分类;
  2. 生成需要执行的 Material / Shading Bin;
  3. 重建或获取顶点属性;
  4. 执行材质计算;
  5. 把 Normal、Base Color、Roughness、Shading Model 等写回 Deferred Scene Texture;
  6. 交给 Deferred Lighting、Lumen、VSM 与 Post Process。

UE5 版本持续演进 Nanite Material Shading 的具体 Raster / Compute 组织,因此应以 Capture 中的实际 Event 和目标分支 Shader 为准。稳定事实是:

  • Nanite 并没有取消材质 Pixel Cost;
  • 屏幕上最终可见像素仍需材质求值;
  • Material / Raster Bin 太多会增加分派与状态开销;
  • 复杂材质、Overdraw 和高输出分辨率仍可能让 Base / Material 阶段成为瓶颈。

Nanite 与 Deferred Frame 的接口#

下游系统Nanite 提供什么仍需什么额外表示
Depth / HZBNanite 可见表面深度还要合并传统几何与其他深度生产者
GBuffer可见三角形属性与材质求值入口Deferred Material / Scene Texture 布局
Direct LightingGBuffer 表面Light、Shadow、BRDF 与 Shading Model
VSMCluster 级 Shadow View Cull / RasterPage Marking、Cache、Physical Pool
Lumen Surface Cache高细节 Mesh Capture 可由 Nanite 加速Card / Surface Cache 与 Lumen Scene
Lumen Software RT视觉 Mesh 不是直接被逐三角追踪Mesh Distance Field / Global Distance Field 等表示
Hardware RT目标版本支持的 Ray Tracing Geometry默认可能使用 Fallback / 特殊 Nanite RT 模式
Collision / Navigation不直接把渲染 Cluster 当 Gameplay CollisionSimple / Complex Collision、Nav Mesh 等独立数据

这解释了为什么 Nanite 画面正常,却仍可能有 Lumen 漏光、Ray Tracing 细节不同或 Collision 不一致:各系统消费的场景表示并不相同。

Fallback Mesh#

Nanite Asset 通常还保留一个传统 Fallback Representation,用于 Nanite 不可用或某些不直接消费 Nanite 数据的路径。用途可能包括:

  • 不支持 Nanite 的平台 / Rendering Path;
  • Complex Collision 或编辑器工具;
  • 默认 Hardware Ray Tracing 表示;
  • 特定 Mesh Processing / Baking;
  • Nanite Feature 不支持时的替代路径。

Fallback Relative Error / Triangle Percent 会影响该表示的细节与内存。调低 Fallback 质量可以省资源,但可能让 Ray Traced Shadow、Reflection、Collision 或其他消费者与主视图差异增大。先确认谁在用 Fallback 再调。

Streaming:几何虚拟化不等于无限显存#

Nanite Streaming 的主要预算包括:

  • Cooked Disk Data;
  • Root / Always Resident 数据;
  • GPU Streaming Pool;
  • 每帧 Page Request / Install 带宽;
  • IO 与解压 / 转码;
  • Streaming Feedback 延迟;
  • 大量独特 Mesh / Instance 的 Working Set。

冷启动与稳定帧必须分开#

首次快速飞入复杂区域时:

  • Candidate Traversal 发现缺页;
  • Streaming Request 暴增;
  • IO / Upload 追赶;
  • 暂时使用较粗父层级;
  • GPU Pool 可能淘汰其他 Page。

相机稳定后才适合测稳态 Raster / Material 成本;Streaming 压力测试则应单独记录飞行速度、IO 设备、Pool、Request 与 Visible Error。

什么内容对 Nanite 不友好#

大量叠层与 Aggregate Geometry#

树叶、毛发、草丛和大量薄片会在同一像素深度方向堆积。即使最终只看到最前面一层,Nanite 也可能需要处理许多候选 Cluster / 三角形,Software Raster 与 Visibility Atomic 发生高竞争。

Masked Overdraw#

几何轮廓仍是大片 Quad,但 Opacity Mask 丢弃大量像素。Nanite 不能只凭最终叶片轮廓提前消除所有透明空洞,材质与 Overdraw 成本依然存在。

过度 WPO#

大幅 WPO 让静态 Bounds 和层级 Cull 难以保守且精确。Bounds 扩大后更多 Cluster 成为 Candidate,阴影 / Lumen 表示也可能失配。

极多 Material / Raster Bin#

大量独特材质与 Programmable Feature 组合会打散 Bin,提高 Shader、Dispatch、分类与 Cache 成本。

只有少量低模#

低复杂度、少实例、传统路径已经很便宜的 Mesh 不一定从 Nanite 获得可测收益;Nanite 自身也有固定 Cull / Dispatch / Streaming 开销。

Visualization 与指标#

Nanite Overview / Visualization 常用于观察:

视图 / 指标回答的问题
Overview瓶颈更像 Cluster、Instance、Overdraw 还是 Material?
Triangles / Clusters当前实际选择了多少细节?
Instances同屏 Nanite Instance 规模如何?
Overdraw同像素竞争多少 Nanite 表面?
Material ID / Raster Bins材质与 Programmable Raster 是否打散?
Evaluate WPO哪些区域执行变形路径?
Streaming / Residency是否缺页、请求或 Pool 压力?
VSM NaniteShadow View 重复了多少 Cluster 工作?

具体模式名随版本变化,从 Editor 的 Nanite Visualization 菜单和当前 NaniteVisualizationData 源码确认。

stat Nanite、ProfileGPU 和平台 GPU Capture 需要联合使用:统计告诉规模,Capture 告诉时间花在哪个 Cull / Raster / Material / Streaming Event。

源码阅读地图#

目录 / 符号研究问题
Nanite Builder / DDC 相关模块Source Mesh 怎样变成 Cluster Hierarchy 与 Page?
NaniteResources / Data 结构Root、Page、Hierarchy、Cluster 数据怎样编码?
NaniteSceneProxy.*Component / Asset 怎样注册为 Nanite Instance?
NaniteCullRaster.*Main / Post Cull 与 Raster Graph 怎样组装?
NaniteStreamingManager.*Request、IO、Pool、Install 与 Eviction 怎样运行?
NaniteMaterials.*Raster / Shading Bin 与 Material Pass 怎样建立?
NaniteVisualization.*每个 Visualization Mode 显示的真实量是什么?
Shaders/Private/Nanite/Instance / Node / Cluster Cull 和 Raster Shader 在哪?
VirtualShadowMaps/ 与 Nanite 调用点Shadow View 怎样复用 Nanite Cull / Raster?
Lumen/ 的 Nanite Capture 调用Surface Cache Capture 怎样请求 Nanite 几何?

推荐从一次 GPU Capture 的 Nanite 父事件选择一个 Cull Dispatch,记录其输入 Buffer / Indirect Args,再搜索同名 RDG_EVENT_NAME。不要先从整个 Nanite Shader 目录逐文件阅读。

七个可证伪实验#

H1:Source Triangle 数不等于每帧 Raster Triangle 数#

准备视觉尺寸相同、Source Triangle 数差异巨大的 Nanite Mesh,固定材质和相机。记录 Selected / Visible Cluster、Raster Triangle 与 GPU 时间。

预期:屏幕误差相近时 Nanite 只选择必要细节,Raster 数远小于 Source 数据;极近距离会逐步选择更细 Cluster。

H2:屏幕分辨率会改变 Cluster 选择#

固定相机和 Mesh,分别用 50%、100% Screen Percentage 与不同输出分辨率测试。记录 Cluster / Triangle 与 Raster 路径。

预期:更高有效像素密度需要更细 Cluster;若数量完全不变,检查是否已到最粗 / 最细限制或 Streaming 未驻留。

H3:叠层几何的成本由 Overdraw 主导#

构造相同三角形数的单层表面与几十层紧密叠放表面,保持屏幕覆盖相同。比较 Nanite Overdraw、Software Raster 和总时长。

预期:叠层版本显著更贵,即使最终可见像素接近。

H4:Material / Raster Bin 增加会抬高固定开销#

让同一组几何分别使用少量共享 Opaque Material、很多独特 Material、Masked + WPO 组合。比较 Bin 数、Shader / Dispatch 与 Material 时间。

预期:复杂组合增加 Bin 和 Programmable Raster / Shading 工作;不能只用 Cluster 数解释差异。

H5:大幅 WPO 会削弱 Cull 效率#

固定 Source Mesh 和材质主体,逐级增大 WPO 幅度并正确扩大 Bounds。记录 Candidate / Visible Cluster、Shadow、Lumen 和 Nanite 时间。

预期:Bounds 越保守,更多工作无法在粗层级拒绝;若不扩 Bounds,可能出现错误消失而不是“性能更好”。

H6:冷 Streaming 与热缓存帧是两类瓶颈#

用固定路径第一次高速飞行,再在相同区域重复。记录 Page Request、IO、Pool、Visible Error 和 GPU 时间。

预期:冷路径 Request / IO 较高,重复路径稳态更好;若持续抖动,检查 Pool 与 Working Set。

H7:VSM 会增加额外 Nanite View 工作#

固定主视图,分别关闭阴影、使用少量稳定 VSM Page、制造大量 VSM Cache Invalidation。比较主视图与 Shadow View 的 Nanite Cluster / Raster。

预期:主视图规模不变时,阴影配置仍能显著改变总 Nanite 工作;VSM 不是“免费复用主相机可见 Cluster”。

故障定位表#

症状先看
远处细节迟迟不清晰Streaming Residency / Request / Pool / IO
相机一转物体缺块Bounds、Main/Post Occlusion、Streaming、Programmable Raster
Nanite Draw Call 少但 GPU 仍高Cluster、Overdraw、Raster Bin、Material Shading、VSM
植被非常贵Aggregate Geometry、Masked Overdraw、WPO、Two-Sided Bin
开 WPO 后突然变贵Bounds、Candidate Cluster、Programmable Raster、Shadow
Ray Tracing 轮廓比主视图粗Fallback Mesh / Nanite RT Mode / 目标版本支持
Lumen 表面缓存缺失Lumen Card / Capture 与 Nanite 支持,不只看主视图
碰撞与画面不一致Collision Mesh / Fallback 配置,而非渲染 Cluster
初次飞行卡、停下恢复冷 Streaming / IO / Page Install

本篇建立的心智模型#

Source Mesh
→ Offline Cluster Hierarchy + Streaming Pages
→ GPU Scene Nanite Instances
→ Instance / Node / Cluster Cull
→ Main Pass(Previous HZB)
→ Post Pass(Current HZB)
→ Hardware + Software Raster
→ Visibility / Depth
→ Material / Shading Bins
→ GBuffer / SceneColor
→ VSM / Lumen / Deferred Lighting

下一篇进入 Lumen:它如何维护与主视图不同的 Scene Representation,Surface Cache、Mesh SDF、Global Distance Field、Hardware RT Scene、Screen Probe 和 Radiance Cache 又怎样合作。

官方资料#

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

UE5 渲染管线 05:Nanite Cluster、双阶段遮挡与虚拟化几何
https://example.pages.dev/posts/ue5-rendering-pipeline/05-nanite/
作者
博主
发布于
2026-07-16
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录