想象你是一位乐高积木大师,受邀在广场中央搭建一座 3 米高的城堡,它由 50 万块细碎的积木拼成。如果老老实实把每一块积木都摆在太阳底下,哪怕观众站在 100 米外,你依然在烈日下给每一块积木排队——这就是传统游戏干的事:无论模型离观众多远,都按最精细、最完整的样子绘制,GPU 被浪费在肉眼根本看不见的细节上。 但如果你足够聪明,会怎么搭?远处看不清砖缝,你只需要搭出轮廓;观众走近一步,你再补一层细节;背对观众的墙壁,根本不必贴砖;箱子里的积木,等观众真的走到对应位置才拆包。这样一来,一个人也能轻松指挥 50 万块积木的“实时搭建演唱会”。 Nanite 就是 UE5 引擎里的这套“智能乐高系统”。它把高精模型的三角形拆成一个个“积木包”(Cluster),提前做好简化说明书(LOD),再根据摄像机位置决定拆哪包、细化到哪层、哪些包扔回仓库(剔除与流式加载)。最终,电影级的几十亿三角形模型也能在游戏中以 60 帧流畅运行,美术师再也不用手动制作高、中、低三套模型了。

岗位关联

对 AI 从业者而言,Nanite 的“预处理 + 自适应调度”思想,是理解 AI 生成高模资产如何被实时消费、图形学与 AI 如何衔接的关键一环,也是游戏与 AI 渲染方向面试的高频考点。

目录
  1. 可视化演示
  2. 虚拟几何概述
  3. 微多边形集群
  4. 离线预处理
  5. LOD自适应
  6. 可见性剔除
  7. 渲染管线
  8. 流式加载
  9. 应用与展望
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示UE5 Nanite虚拟几何三大核心:Cluster分割(1M三角网格MSH→8个微多边形集群CL0-CL7每个含4微多边形GPU顶点着色器渲染)、LOD自适应(4级L0 1M近距→L1 100K→L2 10K→L3 1K远距三角形1000x递减相机距离自动切换)、可见性剔除(视锥剔除5对象3可见2剔除+遮挡剔除OCC遮挡物降低Draw Call),三模式切换理解Nanite。

本节配有交互动效(进入视口后自动加载,约 3KB)。

'+C1+'

虚拟几何概述

以前搭乐高城堡,你需要准备五套不同详略的图纸:远景只画轮廓、近景精确到砖块,每换一个位置就要换一张图纸,图纸之间对不上还会“穿帮”。传统 3D 游戏里的角色和场景正是如此——美术师必须为同一个模型手工制作 4 到 6 个 LOD(Level of Detail)版本:高精度几十万面、中等几万面、低模几百面。运行时根据相机距离切换,于是出现了“远处棱角分明、近处突然跳出一个精细模型”的现象,业内叫 LOD 切换的 "pop" 跳变。

Nanite 的目标恰恰是终结这套繁琐流程。在 UE5 中,美术师可以直接导入 ZBrush 级别的高模,甚至是从三维扫描仪得到的亿万面资产。引擎在离线阶段自动把它拆碎、分层,运行时按需组合出当前距离下最合适的细节。它实现了“像素级精度”:物体离得越近,渲染结果越接近原始高模;离得越远,三角形数自动降到几十个,但轮廓依然正确。

这就像乐高大师现在只需要准备一份“终极详细图纸”,系统自动为你生成 100 米外看、10 米外看、1 米外看的三套版本,而且三套版本之间无缝衔接——这就是 Nanite 所谓的“虚拟几何”。它把“几何体的复杂度”从建模时的死资产,变成了运行时随时可调度的活资源。

微多边形集群

几十万块积木如果全部散落在广场中央,谁也没法快速找到需要的那块。聪明的做法是先把它们拼成标准的“功能包”:一包墙板、一包塔尖、一包窗框。Nanite 处理的高模可能有数千万甚至数十亿三角形,它同样不会把每个三角形当作独立个体,而是把空间上靠近、几何上连成片的三角形打包成一个 Cluster(集群),每个 Cluster 大约包含 128 个微三角形——这就是“微多边形集群”这个名字的由来。

打包过程中,系统同时计算每个 Cluster 的“简化误差”。误差度量用到了 QEM(Quadric Error Metrics,二次误差度量),它的作用是:当我们要把两个顶点合并成一个时,找到最不破坏原始形状的新顶点位置。

E(v)=∑i=1k(ni⋅v+di)2\displaystyle E(\mathbf{v}) = \sum_{i=1}^{k} (\mathbf{n}_i \cdot \mathbf{v} + d_i)^2

1. 顶点位置 $\mathbf{v}$:我们要找的合并后的新顶点坐标。

v=(vx,vy,vz)\mathbf{v} = (\mathbf{v}_x, \mathbf{v}_y, \mathbf{v}_z)

2. 平面方程 $\mathbf{n}_i \cdot \mathbf{v} + d_i = 0$:原始网格中第 $i$ 个邻接三角面所在平面的方程,$\mathbf{n}_i$ 是该面的单位法线,$d_i$ 是平面到原点的偏移距离。

ni⋅v+di=0\mathbf{n}_i \cdot \mathbf{v} + d_i = 0

3. 偏差量计算:把新顶点代入平面方程,得到的值代表它偏离了这个平面的程度,偏离为 0 恰好在平面上。

ni⋅v+di\mathbf{n}_i \cdot \mathbf{v} + d_i

4. 平方再累加:对周围所有 $k$ 个邻接面的偏差取平方后求和,避免正负抵消。

∑i=1k(⋅)2\sum_{i=1}^{k} (\cdot)^2

5. 最小化目标:求 $E(\mathbf{v})$ 的最小值,即可得到简化时最不容易被看出变化的顶点落脚点。

min⁡vE(v)\min_{\mathbf{v}} E(\mathbf{v})

这就像整理散乱积木时还要掂一掂每包的“重心”:把两块不规则积木拼到一起时,选择一个最不破坏整体造型的位置来粘合。QEM 就是那个默默帮你反复试重心、直到形状几乎无感变化的“手感”。

离线预处理

开工之前,乐高大师先把每个功能包拍好照片、编好说明书,放进仓库货架,并标注“墙板包”从远到近的三个版本分别在哪个格子。这样到了现场,工人只需要按距离索引号取货。Nanite 的离线预处理(Build 阶段)就是做这件事——它发生在游戏打包时,而不是运行时,目标是让运行时“只做选择题,不做计算题”。

离线预处理有三个核心步骤。第一步是构建 BVH(Bounding Volume Hierarchy,包围盒层级):把所有 Cluster 组织成一颗包围盒树,树的叶子是 Cluster,祖先节点是包住它们的大包围盒。这就像一座城市按“省—市—区—街道”分层导航,查找某个积木包时无需翻遍全城。第二步是聚类简化:从最精细的原始网格出发,用 QEM 把相邻 Cluster 两两合并、逐级简化,形成从 100% 到大约 0.1% 细节的连续 LOD 序列。第三步是数据压缩烘焙:压缩顶点位置、法线和 UV,并预计算误差信息,打包成引擎资源。好比用符号化的说明书代替实物照片,占地小、读取快。

整个 Build 过程可以类比为“为乐高城堡编写一本超级厚的智能说明书”。说明书不是给人类看的,而是给引擎运行时快速查阅的。有了它,游戏运行时根本不需要知道原始模型长什么样,只需要知道“我现在需要哪个精度等级的哪些积木包”。这本说明书,是 Nanite 一切魔法的基础。

LOD自适应

观众站在 100 米外,你只搭出城堡轮廓;走到 10 米外,补上窗框;走到 1 米外,砖缝纹理全上。人眼的分辨率决定了你该加工到多细。Nanite 在运行时为每个 Cluster 计算一个关键指标——屏幕空间误差(Screen-Space Error):这个 Cluster 的几何误差会占据屏幕上多少个像素。如果小于一个像素的阈值,人眼就分不清再添细节带来的差别,于是不再细分。

ϵscreen=ϵworld×H2×d×tan⁡(θ2)\displaystyle \epsilon_{screen} = \frac{\epsilon_{world} \times H}{2 \times d \times \tan\left(\dfrac{\theta}{2}\right)}

1. 世界误差 $\epsilon_{world}$:简化后的 Cluster 与原始网格的最大几何偏差,单位是米。

ϵworld=max⁡∥简化网格−原始网格∥\epsilon_{world} = \max\| \text{简化网格} - \text{原始网格} \|

2. 屏幕高度 $H$:渲染目标在垂直方向的像素数量,比如 1080p 的 H 就是 1080。分辨率越高,同样偏差越容易被看出。

H=1080H = 1080

3. 相机距离 $d$:物体表面点到摄像机位置的直线距离,单位与 $\epsilon_{world}$ 保持一致。

d=∥pcam−pobj∥d = \|\mathbf{p}_{cam} - \mathbf{p}_{obj}\|

4. 垂直视场角 $\theta$:摄像机在垂直方向能看到的角度范围,通常取 60° 到 90°。

θ=60∘\theta = 60^\circ

5. 正切投影换算:除以 $\tan(\theta/2)$ 把三维角度关系映射到二维屏幕平面,保证与像素单位一致。

tan⁡(θ2)\tan\left(\frac{\theta}{2}\right)

6. 综合判定:当 $\epsilon_{screen}$ 小于阈值(一般设为 1 像素)时,停止继续细分;否则切换到更精细的 Cluster。

ϵscreen≤1 px⇒停止细分\epsilon_{screen} \le 1 \text{ px} \Rightarrow \text{停止细分}

Nanite 的光栅化也因此分成两条路径:三角形在屏幕上足够大时使用 GPU 硬件光栅化,效率很高;当三角形投影小于一个像素时,硬件光栅化反而会因大量极小三角形而效率骤降,这时 Nanite 会切换到“软光栅化”路径,用软件逐像素处理。这就像你不再用大铲子去铲芝麻——换一把镊子反而更快。整个过程对每个 Cluster 独立决策,于是整个画面呈现出连续的、几乎无跳变的细节过渡。

可见性剔除

面向观众的正面要精雕细琢,背面的墙随便砌平就行;被舞台幕布完全挡住的部分,连砌都不用砌。乐高大师在现场绝不会把 50 万块积木全摆出来,他只拆“观众看得见、又没被挡住”的包。Nanite 的树状结构让剔除不需要遍历几十亿三角形,而是在 BVH 树上层层筛:先问“这个区可能在视野里吗?”,再问“这个街区被前面的大楼挡住了吗?”

剔除分为三个级别。第一是视锥剔除:Cluster 的包围盒完全在相机视锥体之外,直接跳过。第二是遮挡剔除:利用上一帧生成的深度缓冲(HZB,Hierarchical Z-Buffer)快速判断该 Cluster 是否被更近的物体完全挡住。第三是背面剔除与小集群合并:只有面向相机的三角形才被绘制,而极小、几乎退化成点的 Cluster 会被合并成一个打包的绘制单元,减少 GPU 调度开销。

在这些机制的共同作用下,实际绘制的三角形数量大约可以表示为:

Ndrawn=Ntotal×rfrustum×rocclusion×rlod\displaystyle N_{drawn} = N_{total} \times r_{frustum} \times r_{occlusion} \times r_{lod}

1. 总三角形数 $N_{total}$:模型原始导入时的全部三角形,比如一亿。

Ntotal=100,000,000N_{total} = 100{,}000{,}000

2. 视锥保留率 $r_{frustum}$:落在摄像机视锥范围内的三角形占比,大量场景外物体在这里被筛掉。

rfrustum=N在视锥内Ntotalr_{frustum} = \frac{N_{在视锥内}}{N_{total}}

3. 遮挡保留率 $r_{occlusion}$:经过深度缓冲测试后仍然可见的三角形占比。

rocclusion=N未被遮挡N在视锥内r_{occlusion} = \frac{N_{未被遮挡}}{N_{在视锥内}}

4. LOD 保留率 $r_{lod}$:经过 LOD 简化后实际保留的三角形占比,远距离模型被大幅降面。

rlod=NLOD后N未被遮挡r_{lod} = \frac{N_{LOD后}}{N_{未被遮挡}}

5. 连乘结果:三个比例依次相乘就是最终绘制数量,每一步都显著降低渲染压力。

Ndrawn≪NtotalN_{drawn} \ll N_{total}

一辆装满积木包的货车开到现场,你只拆开“面向观众且没被幕布挡住的包”,其余原封不动放回车上。正是因为这三个“筛子”层层削减,50 万块积木的搭建才能快到实时——这也就是 Nanite 在 Epic 官方演示中,一个场景塞下几十亿三角形还能保持流畅的秘密。

渲染管线

一个有经验的施工队,会有人专门递料、有人专门砌墙、有人专门质检,绝对不让所有人同时等待同一把铲子。传统引擎里模型面数一旦升高,CPU 向 GPU 发送绘制命令(Draw Call)的次数就会成为瓶颈——每换一次材质、每换一个网格,都要“喊一嗓子”GPU 准备。喊的次数多了,GPU 再快也追不上。

Nanite 的解决方案是 GPU Driven Rendering(GPU 驱动渲染):让 GPU 自己决定画什么,而不是 CPU 逐条指挥。具体来说,它把整个场景的 Cluster 信息预先放进显存,运行时由 compute shader 批量完成视锥剔除、遮挡剔除和 LOD 选择,然后合并绘制调用。同一材质、同一状态的几万个 Cluster 被合并成几百次大绘制调用,CPU 从“话痨”变成了“只宣布大计划”。

为了进一步压榨效率,渲染管线还做了材质排序:不透明物体从近到远排序、透明物体从远到近排序,减少过绘制和混合切换开销。与此同时,遮挡剔除、LOD 选择等计算被放进异步计算队列,与主光栅化任务并行执行,互不阻塞。就像施工队把“能用同一种砖、同一种墙纸的区域”列成一张大清单,一次刷完所有墙面再换下一张清单。整套管线围绕“减少切换、批量执行、并行计算”三个原则运作,让高密度的场景依然能保持高帧率。

流式加载

仓库管理员不会一次性把 5000 箱积木全推到广场上——他只把观众接下来 5 分钟可能用到的几箱推过去,用完再推回来换新箱。Nanite 的虚拟几何库同样采用“按需取用”策略,这是它区别于传统引擎的关键设计之一。传统游戏进入关卡时会把整个静态网格加载进内存,模型越大,启动越慢、内存占用越高。

Nanite 的流式加载机制包括三个层面。第一是按需分配:只有摄像机附近的 Cluster 才会从磁盘流式读取,距离远的 Cluster 在内存里只保留 BVH 元数据,不占三角形存储。第二是内存池管理:已加载的 Cluster 进入一个 LRU(Least Recently Used,最近最少使用)优先队列,长期不用的自动淘汰,为新数据腾出空间。第三是虚拟纹理:贴图同样按屏幕上的需求分块加载,高分辨率纹理只在物体靠近相机时才被调入,远处只加载低分辨率 mipmap。

这套机制让“无限精细”的虚拟世界成为可能。想象一下,一座城市级的乐高乐园,你走到哪里,哪里的积木包就从仓库送上“施工现场”传送带,离开视线范围又自动退回去。Nanite 的流式加载正是这样一条双向传送带——现场永远不会被积木盒淹没,仓库与 GPU 之间永远只有“够用的那一批”在流动。

应用与展望

这套“智能积木系统”不只服务于城堡——城市、雪山、宇宙飞船,乃至整个乐高主题乐园都能用同一套说明书体系。Nanite 带来的不只是画面升级,更是一次渲染范式的转变:从“省着花”变成“可劲儿花”。它让美术师不再与面数搏斗,也让引擎第一次能直接承载影视级的数据量。

在实际应用层面,Nanite 正在三个方向改变行业。第一是游戏开发:美术师可以直接导入 ZBrush 雕刻或摄影测量扫描的高模,无需手动烘焙法线贴图、无需制作多档 LOD,开放世界场景的模型密度和视觉真实度大幅提升。第二是影视渲染:创作者可以在引擎里实时预览电影级 CG 场景,灯光、镜头、资产迭代速度比传统离线渲染快几个数量级,虚拟制片流程因此普及。第三是 AI 资产生态:AI 生成的 3D 模型往往面数恐怖、拓扑混乱、充满自交和冗余三角形,而 Nanite 对三角形并不要求规整拓扑,恰好能“消化”这类未经人工清理的 AI 资产。

可以说,Nanite 把“几何复杂度”从建模阶段的死资产,变成了运行时随时可调度的活资源。过去的美术流程是“手工打磨十套图纸”,而现在只需要给出“一座城堡”的白模,自动分拣、说明书编写、现场搭建全部交给智能系统——未来结合 AI 生成资产,游戏与影视的内容生产力将再次翻倍。

---

AI 应用场景

场景一:AI 生成 3D 资产的实时预览流水线

阶段:数据后处理与实时渲染

解决的问题:AI 生成的 3D 网格面数往往从几十万到几千万不等,且拓扑混乱、存在自交和冗余。传统流程需要人工清理网格、手动制作多档 LOD 才能进入游戏引擎,一个模型可能折腾数天。Nanite 让未清理的高模直接进入引擎,运行时自动评估细节并剔除不可见部分。

具体案例:某工作室用 Stable Diffusion 配合深度估计生成城市建筑的粗略网格,再用 AI 超分模型上采样为高精度网格,直接导入 UE5 用 Nanite 渲染。美术师只需要检查场景布局,而不再逐模型清理拓扑和制作 LOD。

场景二:自动驾驶仿真的大规模场景渲染

阶段:仿真训练环境构建

解决的问题:自动驾驶仿真需要渲染城市级几何场景,传统引擎以三角形面数为性能核心,无法同时承载高精建筑扫描资产与实时传感器渲染。Nanite 的流式加载与可见性剔除,让“数据驱动的逼真场景”在普通工作站上也能跑满帧率。

具体案例:仿真团队用摄影测量生成城市真彩网格(含建筑立面、地形、交通设施),导入 UE5 开启 Nanite 后,配合多路虚拟摄像头传感器仿真,在闭环测试中实时渲染出与真实街道几乎一致的图像数据,供感知模型训练使用。

Python 演示

python49 行
import math  def screen_space_error(world_error, screen_height, distance, fov_deg):    # 世界空间误差映射为屏幕像素数    fov_rad = math.radians(fov_deg)    return (world_error * screen_height) / (        2.0 * distance * math.tan(fov_rad / 2.0)    )  def build_lods(initial_tris):    # 模拟离线预处理: 逐级减半生成 4 级 LOD    lods = []    n = initial_tris    for level in range(4):        lods.append({            "triangles": max(n, 12),            "error": 0.5 / (level + 1)        })        n = n // 2    return lods  def pick_lod(lods, distance, screen_height=1080, fov_deg=60, threshold=12.0):    # 从粗到细选择第一个满足误差阈值的 LOD    chosen = lods[0]    for lod in lods:        chosen = lod        err = screen_space_error(lod["error"], screen_height, distance, fov_deg)        if err <= threshold:            break    return chosen  def simulate():    # 模拟相机从远到近时 Nanite 自动切换 LOD    lods = build_lods(1000000)    print("相机距离(m) | LOD三角形数 | 屏幕误差(px) | 结论")    for dist in [100.0, 60.0, 30.0, 12.0, 5.0, 2.0, 0.8]:        lod = pick_lod(lods, dist)        err = screen_space_error(lod["error"], 1080, dist, 60)        verdict = "精细度足够" if err <= 12.0 else "已用最细LOD"        print(f"{dist:10.1f} | {lod['triangles']:>11,} | "              f"{err:12.2f} | {verdict}")  if __name__ == "__main__":    simulate()
目的:用 Python 模拟 Nanite 的核心决策——根据相机距离计算屏幕空间误差,自动选择 LOD 精度,并观察三角形数量的变化。
  1. return (world_error * screen_height) / (2.0 * distance * math.tan(fov_rad / 2.0))这就是第 4 节屏幕空间误差公式的代码化,把米制的世界误差换算成“占多少个屏幕像素”。
  2. lods.append({"triangles": max(n, 12), "error": 0.5 / (level + 1)})模拟离线预处理阶段生成的 LOD 序列,每级记录三角形数和简化误差。
  3. n = n // 2每级 LOD 三角形数减半,模拟 Nanite 对 Cluster 逐级合并简化的效果。
  4. for lod in lods:从最粗到最细依次尝试,找到第一个满足误差阈值的 LOD。
  5. if err <= threshold: break误差满足阈值就停止细分,这是 Nanite“肉眼分不出就不多画”的核心决策。
  6. lod = pick_lod(lods, dist)把“选哪级细节”的逻辑封装成函数,对应 Nanite 运行时的自适应 LOD 选择模块。

常见误区

误区学了 Nanite 之后觉得 LOD 是古老技术,所有模型都不用做 LOD,传统 LOD 可以直接抛弃了。

正解Nanite 只作用于静态网格几何体。骨骼动画驱动的角色、布料模拟、植被、半透明物体等仍然需要传统 LOD 或其他优化手段。而且 Nanite 内部依然在做"LOD"——只是把手工制作多档模型的工作,变成了离线预处理自动生成连续细节等级。它没有消灭 LOD 思想,而是把 LOD 自动化了。

为何常见:因为 Nanite 的宣传重点就是“无需手动 LOD”,容易被误解为“没有 LOD”,实际上它是把 LOD 搬到引擎内部自动运行。

误区很多人以为 Nanite 是一个“自动减面工具”,开启后模型就变低模了,像 Blender 里的 Decimate 修改器。

正解Nanite 的定位是虚拟几何与自适应调度。当物体靠近相机时,它尽可能还原原始高模的精度,接近像素级;只有远离时才自动简化。它不是一个固定的减面流程,而是一个“按需供应”的渲染系统。减面只是远距离时的一个副作用,核心是让 GPU 只在必要的地方花三角形。

为何常见:因为人们看到远处模型三角形大幅减少,就误以为 Nanite 的作用就是“压低面数”,忽略了它在近处保持精度的另一半功劳。

误区既然 Nanite 这么强,那场景里放几百万个 Nanite 物体也毫无压力,什么都不用管。

正解Nanite 擅长让“单个大网格”的海量三角形流转起来,但它的优化对象是三角形光栅化。当场景里有海量微小物体、大量半透明材质或需要深度混合的物体时,过绘(Overdraw)和材质排序仍然是瓶颈。另外每个 Nanite 实例都有 Transform 和状态开销,实例太多依然会拖慢速度。它把瓶颈从“三角形数量”转移到“绘制批次与着色复杂度”,但瓶颈并没有消失。

为何常见:因为宣传中“几十亿三角形”的数字太震撼,让人以为 Nanite 是万能加速器,忽略了 GPU 还有其他的墙。

误区以前玩 3A 游戏经常看到远景物体走近时“啪”一下变精细,Nanite 应该也一样,只是切换得更频繁。

正解Nanite 的 LOD 切换发生在 Cluster 粒度,而不是整个模型粒度,并且以屏幕空间误差为统一标准。不同 Cluster 根据距离各自独立切换,加上切换阈值控制在 1 像素以内,视觉上基本不可感知。它不是“整个模型换一套皮肤”,而是“哪块砖该补就补哪块”,因此几乎没有 pop 跳变。

为何常见:人们习惯用传统 LOD 的整体切换模型来理解 Nanite,忽略了它在 Cluster 级别的细粒度独立决策机制。

面试题

Q1. Nanite 最核心的目标是解决什么问题?

单选题 · easy

  • A.让材质渲染更真实
  • B.高模无手工LOD渲染← 正确答案
  • C.加速骨骼动画绑定
  • D.改进物理碰撞精度

答案:B。Nanite 的核心目标是让高精模型无需手工制作多级 LOD 就能实时渲染,就像乐高城堡只需要一份完整图纸而不必手工绘制五张远近不同的简化图。A 属于材质范畴,C 与骨骼绑定相关,D 属于物理系统,均非 Nanite 的主攻方向。

Q2. Nanite 中每个 Cluster 大约包含多少个微三角形?

单选题 · mid

  • A.约 8 个三角形
  • B.约 32 个三角形
  • C.约 128 个三角形← 正确答案
  • D.约 4096 个三角形

答案:C。Nanite 把空间上连成片的三角形打包为 Cluster,官方默认每个 Cluster 约 128 个微三角形,就像把散积木按“墙板包”打包。8 个和 32 个太小,调度开销过大;4096 个太大,剔除与 LOD 切换不够精细,所以 C 正确。

Q3. 下列哪些属于 Nanite 在运行时使用的可见性剔除手段?

多选题 · mid

  • A.视锥剔除← 正确答案
  • B.遮挡剔除← 正确答案
  • C.背面剔除← 正确答案
  • D.光照烘焙剔除

答案:ABC。Nanite 在 BVH 树上做视锥剔除,用上一帧深度缓冲做遮挡剔除,同时只绘制面向相机的三角形(背面剔除)。它和乐队演出时“只面向观众的乐器露面”是同一个道理。光照烘焙剔除发生在离线预处理阶段,不属于运行时可见性剔除,因此不选 D。

Q4. 屏幕空间误差 ε_screen 与相机距离 d 的关系是?

单选题 · mid

  • A.与距离成正比
  • B.与距离成反比← 正确答案
  • C.与距离无关系
  • D.恒等于一个像素

答案:B。由屏幕空间误差公式可见 d 位于分母上,距离越大误差越小,因此成反比。就像同一根头发,放在眼前清清楚楚,退到 10 米外就看不见了。A 说反了,C、D 与公式矛盾。

Q5. 关于 Nanite 的离线和运行时流程,下列说法正确的是?

多选题 · hard

  • A.离线构建BVH加速结构← 正确答案
  • B.离线聚类并简化网格← 正确答案
  • C.运行时按需流式加载← 正确答案
  • D.运行时重切全部三角形

答案:ABC。Nanite 的离线预处理阶段完成 BVH 构建、Cluster 聚类和逐级简化,运行时则在 BVH 之上按需流式加载 Cluster 并做剔除与 LOD 选择。就像乐高说明书在工程前写好,施工现场只按图取料。运行时重新分割所有三角形既不现实也无必要,D 错误。

Q6. Nanite 为什么在三角形投影小于一个像素时改用软光栅化?

单选题 · mid

  • A.硬件光栅化效率下降← 正确答案
  • B.GPU 变得更耗电发热
  • C.三角形总数量变少
  • D.场景遮挡查询失败

答案:A。当三角形投影小于一个像素时,GPU 硬件光栅化单元的工作效率会急剧下降,因为每个极小三角形都要消耗固定的硬件流水线开销。Nanite 转用软光栅化逐像素高效处理,就像用大铲子铲芝麻反而慢,换镊子更快。B、C、D 均与该机制无关。

Q7. 下列哪种对象不适合使用 Nanite 渲染?

单选题 · hard

  • A.静态岩石高精度扫描
  • B.骨骼动画角色模型← 正确答案
  • C.建筑扫描点云转换网格
  • D.ZBrush 高模雕刻输出

答案:B。Nanite 面向静态网格几何,骨骼动画驱动的角色需要逐帧更新顶点位置和法线,其动态性质与 Nanite 的静态 Cluster 结构不匹配,因此需要走传统蒙皮渲染管线。岩石扫描、建筑网格和 ZBrush 雕刻都属于静态高模,非常适合 Nanite——就像乐高城堡的墙体可以预先拼好,但旋转木马上的小人必须现场活动。

Q8. QEM(二次误差度量)主要用于哪种操作?

单选题 · easy

  • A.顶点合并位置计算← 正确答案
  • B.材质颜色空间转换
  • C.骨骼权重自动分配
  • D.纹理采样坐标生成

答案:A。QEM 用于边坍缩简化时选择新顶点的最优位置,使得简化导致的几何形状变化最小。好比合并不规则积木时,要找一个最不破坏轮廓的重心点来粘合。B、C、D 分别属于着色、蒙皮和纹理管线,与几何简化无关。

Q9. Nanite 相比传统手动 LOD 流程的优势有哪些?

多选题 · easy

  • A.美术无需手动多档LOD← 正确答案
  • B.减少接缝和切换突跳← 正确答案
  • C.自动像素级细节精度← 正确答案
  • D.彻底免除所有绘制调用

答案:ABC。Nanite 自动生成连续 LOD、以像素误差为标准控制切换、避免传统 LOD 的 pop 跳变,这三点都是实打实的优势。但“彻底免除所有绘制调用”过于绝对——Nanite 只是合并绘制调用,把 CPU 驱动的几千次调用合并成 GPU 驱动的几百次,绘制逻辑仍然存在,因此 D 错误。

Q10. 关于 Nanite 的流式加载,最准确的理解是?

单选题 · hard

  • A.加载全部Cluster进显存
  • B.只加载视锥需要的Cluster← 正确答案
  • C.按磁盘物理顺序全量加载
  • D.随机访问所有微三角形

答案:B。Nanite 的流式加载只在运行时按需读取视锥内且被需要的 Cluster,其余数据继续留在磁盘或内存池外,避免显存被无关三角形占满。这就像乐高仓库管理员只把观众当前需要的那几箱积木推上“施工现场”传送带。A 一次性全加载违背按需原则,C 的全量顺序加载没有调度概念,D 更是毫无索引可言的伪命题。