中EN
概念页

Nanite 虚拟化几何体

Nanite Virtualized Geometry

更新于 2026-10-13 约 12 分钟UE5Nanite虚拟化几何体LOD簇可见性缓冲

Nanite 是 UE5 的虚拟化几何体 (Virtualized Geometry) 系统:导入时把网格切成分层的三角形簇 (Cluster),渲染时按相机视角逐簇选择细节层次并无缝拼接,按需从磁盘流送,并在绕过传统绘制调用 (Draw Call) 的独立通道中渲染,使帧预算不再受多边形数、绘制调用和网格内存约束。

原理

官方描述的工作方式只有两步:(Nanite Virtualized Geometry Overview)

  1. 导入时:网格被分析并拆成"三角形组的分层簇"。
  2. 渲染时:根据相机视角,以不同细节层次即时替换簇,且同一对象内相邻簇"完美衔接无裂缝";数据按需流送,只有可见细节需要驻留内存;Nanite 在自己的渲染通道中运行,"完全绕过传统绘制调用"。

下图表示数据流:离线构建簇层级,运行时按屏幕误差选簇并按需流送。

flowchart LR
    A["源网格<br/>高模/扫描"] --> B["导入: 分层簇构建+压缩"]
    B --> C[("磁盘: Nanite 数据")]
    C -->|"按需流送"| D["GPU 驻留簇"]
    E["相机视角"] --> F["逐簇选 LOD + 剔除"]
    D --> F --> G["Nanite 独立光栅通道"]
    G --> H["进入延迟管线 材质着色"]

与通用理论的关系:

  • 传统 细节层次 是"每个网格几档离散 LOD + 切换距离",切换时会跳变;Nanite 把 LOD 粒度细化到簇,自动处理、无需手工设置 LOD,官方称 LOD 过渡时"质量损失罕见或不存在"。(Nanite Virtualized Geometry Overview) 簇层级的生成离不开 网格简化(官方页面未说明简化细节;Epic 的 SIGGRAPH 2021 讲稿称每簇 128 个三角形,簇组合并后简化再拆分,形成 DAG 而非树,误差用二次误差度量 (QEM) 计算并投影成屏幕像素误差,见下文「内部实现」)。
  • 逐簇剔除把 剔除技术 与 遮挡剔除 的粒度从"每图元"降到"每簇";Nanite 网格适合作为其他 Nanite 几何的"主要遮挡体"。(Nanite Virtualized Geometry Overview)
  • "绕过绘制调用"相当于把 绘制调用与状态切换优化 中的 CPU 提交瓶颈整个移到 GPU 驱动 (GPU-driven) 的流程中。官方概览页没有展开 Nanite 内部如何光栅化与着色,下文「内部实现」一节依据 Epic 的 SIGGRAPH 2021 讲稿补充,可参考理论页 延迟纹理与可见性缓冲 理解这类思路,但不能当作 UE 的确切实现。
  • 与 大场景渲染与虚拟纹理 的类比:官方明确说虚拟纹理对纹理数据要实现的目标,正是 Nanite 对网格数据实现的目标,二者正交但"强烈推荐"一起用。(Nanite Virtualized Geometry Overview)

内部实现:可见性缓冲与软件光栅化(SIGGRAPH 2021)

以下来自 Brian Karis 等在 SIGGRAPH 2021「Advances in Real-Time Rendering」课程上的 Nanite 讲稿,属于 UE5 早期访问版时期的资料,5.8 的实现细节可能已有变化。(A Deep Dive into Nanite Virtualized Geometry (Brian Karis et al., Epic Games, SIGGRAPH 2021 Advances in Real-Time Rendering))

为什么用可见性缓冲:密集网格走传统光栅化有三个问题:光栅化时切换着色器、材质求值的过度绘制(或需要深度预通道)、像素四边形 (Quad) 浪费。Nanite 只往屏幕写「深度 : 实例 ID : 三角形 ID」,然后由每像素的材质着色器读回三角形、变换三个顶点、求重心坐标并插值属性,最后写 G-Buffer。这样没有过度绘制和四边形浪费,每个视图只光栅化一次。这正是 延迟纹理与可见性缓冲 一页讲的思路;讲稿特别说明,只有「对象 ID + 三角形 ID」这种形式才叫可见性缓冲。

软件光栅化:硬件光栅化器按像素并行,适合大三角形,遇到只占几个像素的微多边形效率很低。Nanite 用计算着色器按三角形并行做软件光栅化,讲稿称平均比他们最快的图元着色器 (Primitive Shader) 实现快 3 倍。深度测试改用 64 位原子操作:对可见性缓冲做 InterlockedMax,高位放深度,低位放可见簇索引和三角形索引(最多 34 位)。三角形边长小于 32 像素的簇走软件光栅化,更大的走硬件光栅化,但硬件路径也不绑定颜色/深度目标,同样用原子写入 UAV。

剔除:用两遍遮挡剔除 (Two-Pass Occlusion Culling):先用上一帧的 HZB 和上一帧变换测试并绘制可见物体,再用刚绘制的结果建本帧 HZB,补画新暴露出来的物体。对照 遮挡剔除。

flowchart LR
  A["实例/簇剔除<br/>上一帧 HZB"] --> B{"簇三角形边长"}
  B -->|"< 32 像素"| C["软件光栅化<br/>64 位原子写入"]
  B -->|"较大"| D["硬件光栅化<br/>原子写入 UAV"]
  C --> V["可见性缓冲<br/>深度+簇+三角形"]
  D --> V
  V --> H["构建本帧 HZB → 第二遍剔除"]
  V --> M["材质通道写 G-Buffer"]

图中剔除结果按三角形大小分流到软件或硬件光栅化,两者都写入同一个可见性缓冲;这个缓冲既用来建 HZB 做第二遍剔除,也供材质通道把结果写进 G-Buffer。

在项目中怎么用

  • 启用方式:导入时勾选 Build Nanite;内容浏览器批量右键 Nanite > Enable;或在静态/骨骼网格编辑器里勾 Enable Nanite Support。大项目建议共享 DDC,因为转换需要处理时间。(Nanite Virtualized Geometry Overview)
  • 不用 Lightmass 烘焙光照时,关闭 Generate Lightmap UVs,以免高密度网格多出一套昂贵的 UV 通道和构建时间。(Nanite Virtualized Geometry Overview)
  • 官方建议"在支持的平台上尽可能启用":三角形多/屏幕上很小、实例多、是主要遮挡体、用虚拟阴影贴图投影的网格尤其适合;例外如天空球,但即使开了损失也很小。(Nanite Virtualized Geometry Overview)
  • 已覆盖:静态网格(无 LOD,完整支持 Lumen 和 VSM)、骨骼网格(整个网格一个绘制调用、动画 LOD)、地形、植被、样条网格、静态置换与运行时曲面细分 (Nanite Tessellation)。(Nanite Virtualized Geometry Overview)

与其他 UE5 系统的耦合:虚拟阴影贴图 是为 Nanite 设计的,非 Nanite 几何渲染进 VSM 要贵得多;(Virtual Shadow Maps) Lumen 全局光照与反射 依赖 Nanite 加速表面缓存捕获,植被和实例化静态网格只有用 Nanite 时才被 Lumen 表面缓存支持。(Lumen Technical Details)

限制与坑

类别限制(UE 5.8 文档)
实例数场景最多 1600 万实例(只计已流送的,含非 Nanite)
切线不存逐顶点切线,在像素着色器中推导,边缘可能有不连续
变形只支持刚体变换;WPO 支持但受限(需钳制位移量);不支持 Morph Target
材质只支持 Opaque 和 Masked;自定义表达式(如视差遮蔽)可能有瑕疵(尚无解析导数)
渲染不支持按视图的最小屏幕半径/距离剔除、前向渲染、VR 立体、MSAA、光照通道
光追默认对 Fallback Mesh 做光追;原生 Nanite 光追为实验性 r.RayTracing.Nanite.Mode 1
平台当前主机与 DX12 SM6 桌面;依赖快速流送,推荐 SSD

来源:(Nanite Virtualized Geometry Overview)

取舍:Nanite 把"多边形预算"换成了"磁盘/流送带宽 + 平台门槛",同时与前向渲染、MSAA、VR 不兼容;官方也提醒实例数、单网格三角形数、材质复杂度、输出分辨率等仍要针对内容和硬件实测(帧预算见 帧时间预算与渲染性能)。半透明和大量 WPO 动画的内容仍需走传统网格并做好 LOD。

GEA 的视角:从 LOD 树到 LOD 图(卷 II 11.6.8)

GEA 卷 II 11.6.8 用一整节介绍虚拟化几何体与 Nanite,主要依据 Karis、Stubbe、Wihlidal 在 SIGGRAPH 2021 的《Nanite: A Deep Dive》,与本页「内部实现」一节的资料同源,但从通用渲染原理的角度讲得更完整。

从虚拟纹理到虚拟化几何体

  • 虚拟纹理把带 mip 的大纹理切成瓦片,只把当帧需要的瓦片和 mip 级载入显存;虚拟化几何体把同样的原则用在三维几何上(见 大场景渲染与虚拟纹理)。
  • GEA 说相关思想早已存在,但直到 Brian Karis、Rune Stubbe、Graham Wihlidal 等人为 UE5 开发的 Nanite 才有了高效利用 GPU 的实时实现;2020 年 Nanite 亮相后,其他团队也为自己的引擎开发了类似技术。

LOD 链 → LOD 树

  • 简单的 LOD 链适合小模型,但地形、建筑、巨型飞船这类大几何的一部分离相机很近、另一部分很远,需要把模型拆成子网格树,各自独立选 LOD(传统 LOD 的问题见 细节层次 中的 GEA 部分)。
  • LOD 树:把高分辨率源资产切成小三角形簇(例如每簇不超过 128 个三角形)作为叶子;选几个相邻簇合并成一个较低分辨率的网格(仍不超过 128 个三角形),作为它们的父节点;逐层重复,直到根节点是一个不超过 128 个三角形、近似整个模型的网格。
  • 渲染时在树上做一次与视角相关的"切割":选尽可能低分辨率的节点,使得换成其子节点用户也察觉不到差别;换句话说,让每个三角形大约一个像素大。三角形到了像素大小,再小也不会提升画质,所以结果与渲染全部叶节点(即原始影视级资产)几乎没有区别。

裂缝与 LOD 图

  • 简单 LOD 树的问题:折叠边构建上一层时,簇之间会出现裂缝。一种办法是减面时锁定每个簇的外边界边,保证父簇轮廓与子簇相同。
  • 但这很快失效:叶簇的外边被锁定,父、祖父……都必须共享这些边,高分辨率细节会"堆积"在这些边上,减面效率低到不可用。
  • Nanite 的关键洞见:每一层锁定不同的边。把源网格切成最多 128 个三角形的簇,选一组 N 个相邻簇,锁定这组的外边界,减面得到三角形数减半、轮廓不变的新网格;然后把它重新切成 N/2 个新簇。这样 N 个子簇就有了不止一个父簇,树变成有向无环图 (DAG)。
  • 运行时同样对 DAG 做切割;Nanite 的算法保证各组簇的 LOD 决策互相独立,因而能在 GPU 上并行执行。

其他组成部分

  • 层次 Z 缓冲 (HiZ/HZB):本质是带 mip 的深度缓冲,每个上层像素存下层四个像素中的最大深度。剔除时算出簇的屏幕空间范围,找到范围小于 4×4 像素的最低 mip 级,用其包围体的最小深度与之比较,每簇只需一次纹理采样(见 遮挡剔除)。
  • 两遍遮挡剔除:要用 HZB 判断画哪些簇,却要先画簇才能得到 HZB。Nanite 第一遍重画上一帧可见的簇来构建本帧 HZB,再用它测试其余簇,找出本帧新出现的部分。
  • 可见性缓冲:存每个像素的深度、物体 ID 和三角形 ID,把可见性问题与光照问题解耦。GEA 把它比作深度预通道,区别是它既像深度缓冲又像"廉价的 G-buffer",只存足够在之后的光照 pass 中查到材质的信息(见 延迟纹理与可见性缓冲)。
  • 软件光栅化:簇的三角形约一个像素大,而硬件光栅化器为大三角形优化、以 2×2 quad 为单位工作,每个单像素三角形都要渲染整个 quad,极其低效;所以 Nanite 这类引擎用 GPU 上的计算任务做软件光栅化(见 光栅化)。

与本页其他资料的对照

  • GEA 的描述与本页「内部实现」一节(同一份 SIGGRAPH 2021 讲稿)一致,没有发现冲突;本页给出了 32 像素的软硬件分流阈值和 64 位原子写入,GEA 没有涉及这些细节。
  • 原书问题(11.6.8.6):GEA 说 quad 是为了对相邻像素的深度求一阶差分、近似三角形相对相机的斜率,再用于纹理过滤。实际上 2×2 quad 的差分可以对任意插值量或着色器变量求(HLSL ddx/ddy,见 Microsoft Learn "ddx" 文档),纹理过滤选 mip 级用的是纹理坐标的屏幕空间导数,不是深度的导数(同见 硬件光栅化与透视校正插值)。结论"单像素三角形也要付出整个 quad 的代价"不受影响。
  • 书中原文在讲 2×2 quad 时写"在 11.3.10.1 节我们说过",但 quad 光栅化实际在 11.3.10.8 节,属于书中交叉引用笔误。
  1. Nanite Virtualized Geometry Overview UE 5.8 文档
  2. Virtual Shadow Maps UE 5.8 文档
  3. Lumen Technical Details UE 5.8 文档
  4. A Deep Dive into Nanite Virtualized Geometry (Brian Karis et al., Epic Games, SIGGRAPH 2021 Advances in Real-Time Rendering) Epic SIGGRAPH 2021 Advances 讲稿(UE5 早期访问版时期)
  5. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  6. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.6.8 节

相关页面

图形学细节层次Level of Detail细节层次 (LOD) 在物体对图像贡献变小时改用更简单的表示。LOD 系统由三部分组成:生成(简化或手工制作多个版本)、选择(按距离、投影面积等收益函数挑选)、切换(尽量减少跳变 popping)。LOD 主要减少顶点处理,也通过减少 quad 过度着色降低像素开销;进一步还可在预算约束下全局选择 LOD,实现时间关键(恒定帧率)渲染。图形学网格简化Mesh Simplification网格简化(数据缩减、抽取 decimation)在尽量保持外观的前提下减少三角形数,使应用能在低端机器上伸缩。核心操作是可逆的边折叠,用代价函数(典型是 Garland–Heckbert 的二次误差度量 QEM)排序;它产生的渐进网格可用于连续 LOD 与渐进传输,但自动化并非万能。图形学剔除技术Culling Techniques剔除 (culling) 是在渲染前尽快去掉对最终图像没有贡献的部分。本页讲几何类剔除:背面剔除(含成簇背面剔除与法线锥)、视锥剔除(层次化、平面掩码)、室内场景的入口剔除,以及牺牲质量换速度的细节剔除和小三角形剔除。更复杂的遮挡剔除见 遮挡剔除。图形学遮挡剔除Occlusion Culling遮挡剔除尽早剔除被其他物体挡住的物体,避免它们在 z-buffer 中被光栅化、深度比较甚至着色。本页覆盖遮挡剔除的分类与通用框架、GPU 遮挡查询、层次 Z 缓冲 (HZB) 及其在现代引擎中的简化变体(含两遍法、软件光栅化遮挡),以及在 CPU/GPU 上按物体—簇—三角形多粒度组合剔除并用间接绘制提交的剔除系统。图形学延迟纹理与可见性缓冲Deferred Texturing & Visibility Buffer延迟着色避免了着色的过度绘制,但生成 G-buffer 时仍有过度绘制:先画的物体读了大量纹理,被后画的物体挡住后这些带宽全部浪费。延迟纹理只用一遍几何 pass、存极少的数据(纹理坐标与切线基,或仅三角形与实例 ID),直到着色时才读纹理。由于 GPU 算力增长快于带宽,让瓶颈落在计算而非缓冲访问被视为面向未来的做法。图形学绘制调用与状态切换优化Draw Calls & State Change Optimization调用图形 API 的开销主要在 CPU 端的驱动里:状态切换昂贵,每次绘制调用有固定开销,大量小批次会让 GPU"饿死"。对策是:合理放置缓冲;按状态代价排序分组;共享纹理和着色器;合并网格和实例化以减少调用;并用一个整数排序键同时兼顾状态分组与前后排序。图形学大场景渲染与虚拟纹理Large Scenes & Virtual Texturing当场景数据远大于内存(如主机只有 8 GB,而游戏世界有数百 GB)时,需要按需把数据流送进内存。本页讲三类技术:虚拟纹理(把巨大的 mipmap 链切成瓦片,只让可见瓦片驻留在显存,通过页表/间接纹理寻址)、纹理转码(磁盘上用高压缩比的可变码率格式,加载时转成 GPU 块压缩格式),以及按平面瓦片组织资产的通用流送。这些方法几乎总是与剔除和 LOD 配合使用;地形部分见 地形渲染。综合帧时间预算与渲染性能Frame Budget & Rendering Performance本页把 wiki 中分散在 RTR4 第 18~23 章的性能知识串成一条线:一帧的时间预算由最慢的管线阶段决定,先用毫秒帧时间度量并定位瓶颈,再按瓶颈所在位置——CPU/驱动、几何、像素、带宽/内存——选用对应手段;最后从 GPU 硬件机制(占用率、HiZ/early-z、压缩、分块架构)理解这些手段为何有效。各结论的细节与出处见所链接的概念页。游戏开发 · UE5UE5 渲染架构UE5 Rendering ArchitectureUE5 的渲染器是独立的 Renderer 模块,在渲染线程 (Rendering Thread) 上以「场景代理」镜像游戏线程的组件状态,每帧按固定顺序执行深度预通道、G-buffer 基础通道、光照、雾、半透明和后处理。现代渲染代码用渲染依赖图 (Render Dependency Graph, RDG) 声明通道与资源,由 RDG 自动排屏障、复用瞬态内存、并行录制;最终命令经 RHI 线程翻译成 D3D12/Vulkan 等图形 API 调用。默认走延迟着色 (Deferred Shading),也可切换前向着色 (Forward Shading)。游戏开发 · UE5虚拟阴影贴图Virtual Shadow Maps虚拟阴影贴图 (Virtual Shadow Maps, VSM) 是 UE5 默认的阴影方法:概念上就是分辨率极高(虚拟 16k×16k)的阴影贴图,切成 128×128 的页 (Page),只为屏幕上需要着色的像素分配和渲染页,并跨帧缓存;方向光用 clipmap 覆盖大范围,软阴影由阴影贴图光线追踪 (Shadow Map Ray Tracing, SMRT) 生成。它为 Nanite 设计,与 Nanite 一起使用时最高效。游戏开发 · UE5Lumen 全局光照与反射Lumen Global Illumination & ReflectionsLumen 是 UE5 默认的全动态全局光照 (Global Illumination, GI) 与反射系统:先做屏幕空间追踪,未命中再对"Lumen 场景"做软件光追(有符号距离场)或硬件光追,命中点的光照从按网格离线放置的卡片 (Card) 构成的表面缓存 (Surface Cache) 中查询,表面缓存的直接与间接光照分摊到多帧更新,从而得到无限次漫反射弹射和全粗糙度范围的反射。游戏开发 · UE5TSR 与抗锯齿方案Temporal Super Resolution & Anti-AliasingUE5 提供四种抗锯齿:时间超分辨率 (Temporal Super Resolution, TSR,默认)、时间抗锯齿上采样 (TAAU)、快速近似抗锯齿 (FXAA) 和仅前向渲染可用的多重采样抗锯齿 (MSAA)。TSR 是与平台无关的时间性上采样器,用低内部分辨率渲染,借助历史帧累积细节输出接近原生的画面,把节省的 GPU 时间留给 Nanite 与 Lumen。游戏开发 · UE5世界分区World Partition世界分区 (World Partition) 是 UE5 的自动数据管理与基于距离的关卡流送 (Level Streaming) 系统:整个世界存为一个持久关卡,按可配置的运行时网格划分为单元格 (Cell),由流送源 (Streaming Source,默认是玩家控制器) 按距离加载/卸载。它配合一 Actor 一文件 (One File Per Actor, OFPA) 支持多人协作编辑,用数据层 (Data Layers) 按玩法状态切换内容,用分层细节层次 (Hierarchical Level of Detail, HLOD) 在远处以代理网格显示未加载的单元格。游戏开发 · UE5UE5 性能分析UE5 ProfilingUE5 性能分析的基本流程是:先用 stat unit 判断瓶颈在游戏线程、渲染线程还是 GPU,再用对应的 stat 组、profilegpu/GPU 统计或 Unreal Insights 的 Timing/Memory 等视图向下钻取;渲染特性(RDG、VSM、TSR)各自提供作用域和可视化。测量时要避开会扭曲数据的设置(调试构建、异步计算、可视化模式)。游戏开发 · UE5PCG 程序化内容生成框架PCG FrameworkPCG 框架把程序化内容表达为「点流」:PCG 组件/体积从关卡采样空间数据,图中的 Sampler 生成带变换、密度、种子与自定义属性的点,经过滤与变换后由 Spawner 生成网格或 Actor,编辑器中实时更新,也可运行时生成。属性分为 $ 静态属性和元数据动态属性,按 @Data/@Points/@Elements 域组织;图参数与图实例的用法类似材质参数与材质实例;与世界分区集成,生成物继承数据层与 HLOD 层。图形学光栅化Rasterization光栅化(也叫扫描转换)把屏幕空间里带深度和着色数据的顶点,转换成三角形覆盖的像素(片元),交给像素处理阶段。它是几何处理和像素处理之间的同步点:三个顶点在这里组成三角形。图形学图形栈与渲染引擎架构Graphics Stack & Rendering Engine Architecture渲染引擎要解决的"渲染问题"是:给定由场景元素、虚拟光源和虚拟相机组成的虚拟世界,生成相机看到的二维彩色图像。GEA 把它拆成可见性问题和光照问题,按解法把引擎分为光线追踪、深度缓冲光栅化、辐射度和混合四类;光栅化引擎通常采用立即模式的两层结构:下层是图形管线,上层是负责剔除、提交几何和设置着色器参数的应用层。本页讲这套整体架构,管线内部见 渲染管线。图形学网格着色器管线Mesh Shader Pipeline网格着色器管线(也叫网格几何管线)是 GPU 厂商为取代传统光栅管线前段而推出的新架构:光栅化器和像素着色器不变,网格着色器和可选的放大着色器(任务着色器)接管顶点、外壳、域和几何着色器的全部工作。它以类似计算着色器的线程组处理叫 meshlet 的小批图元,像启动计算着色器一样启动绘制,还能把部分应用层工作搬到 GPU 上。2019 年进入 DirectX 12,2022 年以 VKEXTmeshshader 扩展进入 Vulkan。图形学计算着色器Compute Shader计算着色器是 DirectX 11 引入的一种 GPU 计算方式:它不固定在图形管线的某个位置,但由图形 API 调用,和其他着色器共用统一着色器核心。它暴露了线程组和组内共享内存,最大的优势是能直接处理 GPU 上生成的数据,不用来回传给 CPU。图形学硬件光栅化与透视校正插值Hardware Rasterization & Perspective-Correct InterpolationGPU 光栅化由三角形设置与三角形遍历组成。硬件用每条边一个边函数判断采样点是否在三角形内,利用其增量性质按瓦片分层遍历,用左上规则决定恰好落在边上的像素归属,用保护带避免大多数裁剪。边函数的值恰好是子三角形面积的两倍,因此遍历顺带得到重心坐标;透视投影下需要线性插值 a/w 与 1/w 再逐像素相除,得到透视校正插值。本页还介绍 2×2 quad 与辅助像素、保守光栅化。

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原