Nanite虚拟几何体

介绍虚幻引擎5中的虚拟几何体系统——一种可以获得像素级细节和海量对象的系统。

Choose your operating system:

Windows

macOS

Linux

Nanite是虚幻引擎5的虚拟化几何体系统,它采用全新的内部网格体格式和渲染技术来渲染像素级别的细节以及海量对象。它可以智能地仅处理你能够感受到的细节。另外,Nanite采用高度压缩的数据格式,并且支持具有自动细节级别的细粒度流送。

Nanite场景示例

Nanite的优势

  • 几何体形状的复杂度提高了数个数量级,三角形和对象的实时渲染数量达到了前所未有的高度

  • 帧预算不再会因为多边形数量、绘制调用和内存使用情况而受限

  • 现在可以直接导入电影级品质的美术资源,例如ZBrush雕刻模型和摄影测量扫描数据

  • 通过高模实现细节,而非将细节烘培到法线贴图纹理

  • 自动处理细节级别(LOD),不再需要手动设置单个网格体的LOD

  • 品质损失极少或没有损失,特别是在LOD发生过渡时

尽管Nanite带来了前所未有的变革,但在实际使用上,仍会存在一些限制。例如,在考虑实例总数、单个网格体的三角形数量、材质复杂度、输出分辨率、项目性能等方面时,还是需要根据实际项目内容和硬件水平来仔细衡量。与此同时,在虚幻引擎未来的版本中,Nanite将不断扩展功能并提升性能。

Nanite网格体和传统静态网格体的不同之处

Nanite网格体是一种启用了Nanite的特殊静态网格体。Nanite网格体本质上仍是三角形网格体,但对其数据进行了大量细节和压缩处理。此外,Nanite使用了一种全新系统,能以极高效的方式来渲染这种数据格式。

要让静态网格体利用Nanite,只需一个标记来启用它即可。编辑Nanite网格体的内容和传统网格体没太大不同,区别就在于相比使用传统方法渲染的几何体,Nanite能够渲染的三角形和实例要多出数个数量级。将摄像机移到足够近的位置后,Nanite就会绘制出导入的原始源三角形。

Nanite网格体支持多重UV和顶点颜色。材质可以被指定给网格体的不同分段,并且这些材质可以使用不同的着色模型和动态效果(在着色器中完成)。材质指定可以动态切换,就像其他静态网格体一样。Nanite也无需任何烘焙材质的过程。

虚拟纹理并不要求与Nanite一起使用,但非常推荐这么做。虚拟纹理是正交虚幻引擎功能,它与纹理数据的关系类似于Nanite与网格体数据的关系。

使用Nanite前,你应该首先熟悉静态网格体的工作流程,但是目前还有很多内容尚不支持。有关更多细节,请参阅本页面的支持功能小节。

Nanite如何工作?

Nanite可最大限度地与现有的引擎工作流无缝集成,可使用前所未有的方法来存储和渲染网格体数据。

  • 导入期间 — 分析网格体,并将其拆分成由三角形组构成的分层群集。

  • 渲染期间 — 根据摄像机视图以不同LOD,随时切换群集,并且可以在不破坏同一对象中相邻群集的情况下完美连接。数据会根据需求流送,因此只有可见细节才会保存在内存中。Nanite在自己的渲染通道中运行,该通道完全绕过了传统的绘制调用。你可以使用可视化模式来检视Nanite管线。

由于Nanite需要从磁盘快速流送网格体数据,因此建议使用固态硬盘(SSD)来存储运行时数据。

应该将Nanite用于哪些类型的网格体?

一般来说,能启用时应该尽量启用Nanite。启用了Nanite的静态网格体通常可以更快地渲染,占用的内存和磁盘空间会更少。

具体来说,如果网格体满足以下条件,则尤其适合使用Nanite:

  • 包含很多三角形,或屏幕上三角形非常小

  • 场景中有很多实例

  • 是其他Nanite几何体的主要遮挡物

  • 使用虚拟阴影贴图投射阴影

不过有一个例外,那就是天空球之类的对象:它的三角形在屏幕上显得很大,不会遮挡任何东西,并且场景中只有一个。通常,这种例外很少见,并且让它们启用Nanite导致的性能损失很小,所以只要Nanite支持,就不必过度担心是否应该不开启Nanite。

目前Nanite不支持某些情况。有关更多细节,请参阅本页面的支持功能小节。

在网格体上启用Nanite支持

以下方法可在几何体上启用Nanite(前提是几何体支持):

将几何体转换为Nanite时,在每个网格体上都需要花费一些处理时间。在大型项目上,如果有很多Nanite资产,使用共享的派生数据缓存(DDC)将非常有帮助。如需更多信息,请参阅共享DDC文档。

导入静态网格体

在导入要启用Nanite的网格体时,勾选 构建Nanite(Build Nanite) 复选框。

Nanite FBX导入选项

假如不使用Lightmass预计算光照,建议禁用 生成光照贴图UV(Generate Lightmap UVs) 属性。

启用此属性后,高精度网格体会显著增加静态网格体数据的导入和构建时间。此属性还将增加一个额外的UV通道,这对于非常密集的网格体而言将会产生大量的数据。因此,如果你的项目不使用烘焙光照,则没有必要产生这两项开销。

在资产上启用Nanite

假如你的项目已经有了大量内容,并且你希望启用Nanite,那么有两种办法:一是使用内容浏览器批量启用资产,二是在每个资产的编辑器中单独启用。

在网格体上批量启用Nanite

对于你要启用Nanite的批量静态网格体资产,使用 内容浏览器(Content Browser) 选择它们,然后,右键点击 并从上下文菜单选择 Nanite > 启用(Enable)

在内容浏览器中对资产批量启用Nanite

在单独的网格体上启用Nanite

打开支持Nanite的网格体的编辑器,例如静态网格体和几何体集合(Chaos物理驱动的破裂网格体),并通过 细节(Details) 面板启用Nanite。

在静态网格体编辑器(Static Mesh Editor)中,找到 Nanite设置(Nanite Settings) 并选中 启用Nanite支持(Enable Nanite Support) 复选框。

在静态网格体编辑器中启用Nanite

在几何体集合编辑器(Geometry Collections Editor)中,找到 Nanite 分段,并选中 启用Nanite(Enable Nanite) 复选框。

在几何体缓存上启用Nanite

支持的Nanite特性

本小节介绍了如何在虚幻引擎项目中充分利用Nanite的特性,并详细说明了支持和不支持的内容以及可能的限制。

几何体

Nanite可以在静态网格体和几何体集合上启用。

启用了Nanite的网格体可以搭配以下组件类型使用:

  • 静态网格体

  • 实例化静态网格体

  • 分级实例化静态网格体

  • 几何体集合

Nanite目前仅限于刚性网格体。在常见项目场景中,90%以上的几何体都是刚性网格体。Nanite支持刚性网格体的动态平移、旋转和非均匀缩放,但不支持一般的网格体变形,无论是动态还是静态的变形。这意味着,Nanite网格体的位置无法简单地通过将4x3矩阵乘法应用于整个网格体来表达。

变形(Deformation)不支持且不限于以下几点:

  • 骨骼动画

  • 变形目标

  • 材质的世界位置偏移

  • 样条线网格体

此外,Nanite目前还不支持:

  • 自定义深度或模板

  • 在实例上绘制顶点

    • 特指使用编辑器网格体绘制(Mesh Paint)模式进行的逐实例绘制的颜色。

    • 确认 支持在原始网格体上导入的顶点颜色

场景中存在的最大实例数量不大于1600万。这包括场景中的所有流送进来的实例,而不仅仅是为Nanite启用的那些。只有流送进来的实例会被计算在内。

静态网格体启用Nanite时,不会保存静态网格体每个顶点切线的信息。相反,切线空间会在像素着色器中隐式继承。为了减少数据大小,目前没有存储切线数据。使用这种方法的切线空间会有所不同,可能会导致边缘不连续。但是,目前尚无事实证明这是一个重大问题。虚幻引擎未来版本将计划支持顶点切线。

材质

Nanite支持混合模式(Blend Mode)是 不透明(Opaque) 类型的材质。其他材质类型则不被允许,或者对Nanite网格体没有影响。

当检测到不受支持的材质时,系统会指定一个默认材质,并在 输出日志(Output Log) 中放置警告以及附加信息。

以下是Nanite不支持的材质功能:

  • 使用遮罩和半透明的混合模式

  • 延迟贴花

    • 将Nanite网格体用于网格体贴花。

    • Nanite支持将贴花投射到其表面。

  • 线框

  • 双面材质

  • 像素深度偏移

  • 世界位置偏移

  • 自定义逐实例数据

如果在材质中使用以下内容并指定给启用了Nanite的网格体,则会导致网格体显示异常:

  • 顶点插值器节点

  • 自定义UV

渲染

以下渲染功能尚不支持:

  • 使用以下内容的视图相关对象筛选:

    • 最小屏幕半径

    • 距离剔除

  • 正向渲染

  • 虚拟现实中的立体渲染

  • 分屏

  • 多重采样抗锯齿(MSAA)

  • 光照通道

  • 针对细节丰富的Nanite网格体的光线追踪

    • Nanite支持光线追踪功能,但光线只与Nantie网格体的代理模型(回退网格体)相交,而不是与拥有完整细节的Nanite网格体相交。

  • 某些可视化视图模式还不支持显示Nanite网格体

    在查看细节十分丰富的几何体时,在静态网格体编辑器中使用某些可视化模式应该谨慎。查看法线和UV可能会导致编辑器的性能出现问题。

支持的平台

Nanite目前支持PlayStation 5、Xbox Series S|X、以及符合以下显卡要求的PC(需要使用最新显卡驱动并支持DirectX 12):

  • NVIDIA:Maxwell显卡或更新版本的显卡

  • AMD:GCN显卡或更新版本的显卡

PlayStation 4和Xbox One也支持Nanite,但对这些平台的支持目前是实验性的。如果希望在这些平台上发布拥有高保真度的内容,预计Nanite的性能可能无法完全满足要求。

Nanite回退网格体和精度设置

静态网格体中的某些属性可控制Nanite模型的精度以及其代理网格体(也称为回退网格体,相对粗糙一些)的精度。

这些设置可以在静态网格体编辑器 细节(Details) 面板的 Nanite设置(Nanite Settings) 分段下找到。

静态网格体编辑器Nanite设置

Nanite设置包括以下属性:

属性

说明

位置精度(Position Precision)

选择生成Nanite网格体时此网格体应使用的精度。自动(Auto) 根据网格体大小确定适当的精度。此精度可以覆盖,以便提高精度或优化磁盘占用空间。

最低驻留(Minimum Residency)

设置此网格体应始终保留在内存中的内存字节大小,并将其余部分流送进来。值越高,需要的内存越多,但对于某些网格体,这可以减轻流送弹出问题的发生。

保持三角形百分比(Keep Triangle Percent)

从源网格体中保留的三角形的百分比。减少此百分比可优化磁盘大小。

优化相对误差(Trim Relative Error)

设置允许为Nanite网格体移除的最大相对误差量。源网格体中视觉影响小于此相对误差量的所有细节都将被移除。相对误差没有单位大小,与网格体大小有关。默认情况下,Nanite将存储所有原始源网格体的三角形。

回退三角形百分比(Fallback Triangle Percent)

设置减少Nanite源网格体时保留的三角形百分比。当无法使用细节丰富的Nanite数据时(例如平台不支持Nanite渲染),或者使用Nanite数据不现实(例如在复杂碰撞中)时,这将成为粗糙呈现(或回退网格体)。

回退相对误差(Fallback Relative Error)

设置允许为回退网格体移除的最大相对误差量。所生成回退网格体中视觉影响小于此相对误差量的所有细节将一律移除。相对误差没有单位大小,与网格体大小有关。

顶点精度

Nanite会对网格体顶点位置进行量化,以便最大化内存密度并最小化磁盘占用空间。量化步长是二的幂,步长的大小可以通过 位置精度(Position Precision) 属性来选择,以匹配各个网格体的要求。默认设置是 自动(Auto) 根据网格体尺寸以及三角形密度挑选合适的精度。你也可以通过选择精度大小手动覆盖,以便提升精度效果或优化磁盘占用空间。

位置精度的静态网格编辑器Nanite设置

量化(Qantinization)是一种有损压缩形式。而在处理模块化网格体或具有共享边界的网格体时,使用有损压缩特别具有挑战性,特别是当这些边界需要完全对齐,避免几何体中出现孔洞或裂缝时。

为了确保一致性,量化发生在以网格体原点为中心的非标准化对象坐标上。这能确保当网格体使用相同的精度设置,而网格体中心之间的平移是该精度的倍数时,量化不会导致裂缝的出现。

优化数据

有时你需要减少Nanite存储的数据量,优化磁盘大小。Nanite含有一些设置,能让你在生产过程中随时从存储的Nanite网格体中优化细节数据,这意味着你事先过度提升质量也不要紧,稍后相应调整即可。

要优化细节数据,你需要使用 保持三角形百分比(Keep Triangle Percent)优化相对误差(Trim Relative Error) 属性。你可以将它们视为在存储为Nanite网格体之前的预抽取选项。在Nanite的案例中,网格体中的细节不需要统一。最不重要的数据会首先删除,更类似于有损压缩。

使用 保持三角形百分比(Keep Triangle Percent) 设置要从源网格体中保留的三角形百分比。

使用 优化相对误差(Trim Relative Error) 设置从源网格体优化数据时允许的最大相对误差量。凡是删除后会导致相对误差小于此数量的三角形,将一律删除。你也可以这样认为,凡是视觉影响小于该值的细节,将一律优化。相对误差没有单位大小,与网格体大小有关。

这两个属性的默认设置是默认不优化任何内容,Nanite会存储所有原始源网格体的三角形。

优化数据对于减小磁盘大小(即下载大小)很重要,但并不能提高性能。有关此主题的更多信息,请参阅下面的数据大小小节。

回退网格体

虚幻引擎的很多子系统都需要访问以传统方式渲染的网格体提供的传统顶点缓冲。为静态网格体启用Nanite之后,将对细节丰富的网格体生成粗糙呈现,以便在Nanite数据无法使用的情况下访问和使用。回退网格体是在不支持Nanite渲染时使用的生成网格体。它还用于不适合使用细节丰富网格体的情况,例如需要复杂碰撞时,需要使用光照贴图进行烘焙光照,以及使用Lumen进行硬件光线跟踪反射时。

回退三角形百分比(Fallback Triangle Percent) 属性表示原始源网格体中用于生成粗糙呈现的三角形百分比。你可以指定0%到100%之间的三角形百分比,百分比越大,保留的原始网格体细节越多。

回退相对误差(Fallback Relative Error) 设置从源网格体中删除细节时允许的最大相对误差量。凡是删除后会导致相对误差小于此数量的三角形,将一律删除,首先删除视觉影响较小的细节。相对误差没有单位大小,与网格体大小有关。

例如,如果你希望你的网格体完全不进行抽取,你将使用回退三角形百分比100和回退相对误差0。

在下面的比较中,有从原始源网格体创建的细节丰富的Nanite网格体,与生成的Nanite回退网格体的默认设置进行比较。

高模Nanite网格体

Nanite生成回退网格体 | 默认设置

使用回退相对误差指定从原始源网格体中保留多少原始细节,使用回退百分比设置使用多少细节。

在下面的比较中,回退网格体保持100%的回退三角形百分比,但调整回退相对误差,以便使用更多来自原始源网格体的三角形。调整这些值时,你可以在视口中将Nanite三角形的Nanite细节用作更改其值的指示器。

Nanite生成的回退网格体 | 默认设置

Nanite生成的回退网格体 | 调整的质量设置

回退网格体可视化

在静态网格体编辑器(Static Mesh Editor)中,你可以使用 显示(Show) 下拉菜单中的视口 Nanite回退(Nanite Fallback) 选项,在细节丰富的Nanite网格体和Nanite回退网格体之间切换。你也可以使用热键 Ctrl + N 在两个可视化选项之间快速切换。

静态网格体编辑器Nanite回退网格体切换

对启用了Nanite的网格体使用自定义回退网格体LOD

回退网格体在引擎的许多功能中都会用到,例如复杂的逐多边形碰撞、光线追踪、光源烘培等等。它也可用于不支持Nanite的平台。生成回退网格体时,启用了Nanite的网格体始终使用源网格体的 LOD0 槽来自动生成回退网格体。但是,有时需要使用手动指定的回退网格体或一系列传统LOD,而不是自动生成的网格体。

这种控制级别允许你在项目中使用Nanite,同时也可以直接控制你在光线追踪反射中看到的几何体或不支持Nanite的平台中的几何体。

按照以下步骤指定你自己的自定义回退网格体,或使用一系列LOD:

  1. 回退三角形百分比(Fallback Triangle Percent) 设置为 0 ,以便回退网格体尽可能小,因为在使用此方法时它将被忽略。

  2. 使用此传统LOD设置程序将一个或多个LOD添加到网格体。

  3. 使用 LOD导入(LOD Import) 下拉菜单,从 LOD设置(LOD Settings) 分段 导入LOD关卡1(Import LOD Level 1)

  4. LOD设置(LOD Settings) 分段下,将 最低LOD(Minimum LOD) 设置为 1 。这会使得Nanite生成的回退网格体被忽略。

复杂碰撞是一种特殊情况。使用 通用设置(General Settings)用于碰撞的LOD(LOD for Collision) 属性,指定用于碰撞的LOD。所有LOD都可用于碰撞,包括LOD 0。

此特殊方法可能无法让Nanite项目自动兼容不支持Nanite的平台,应该针对你的项目进行测试和评估。

Nanite可以高效处理大量实例,但如果Nanite被禁用,那么可能会出现大量绘制调用,以至于传统渲染管线可能无法应对。你可以使用 r.Nanite 0 来关闭和开启Nanite支持,测试它在你的项目中是否可行。

更多信息,请参阅此页面的控制台变量和命令小节。

性能以及内容相关的问题

大多数情况下,Nanite能很好地随屏幕分辨率的变化而变化。能这样做是基于两项关键技术:精细的细节级别和遮挡剔除。通常这意味着,无论场景中的源数据的几何复杂度如何,Nanite实际试图绘制到屏幕上的三角形的数量会始终与像素的数量成正比。

Nanite遵循的设计理念是,三角形的绘制数量超过像素数量就是一种浪费。

某些情况下,有些类型的内容会破坏Nanite采用的缩放技术,但这不意味着完全不应将Nanite用于这些内容,也不意味着它的渲染速度会慢于传统管线。对于这类内容,这只是意味着基于像素缩放而非基于场景复杂度缩放不再适用于它们。请使用虚幻引擎的分析功能来监控这类情况的发生。

聚合几何体

聚合几何体(Aggregate geometry )是指许多不连贯的对象在远处合并成单个体积,例如毛发、树叶和草。这种类型的几何体打破了Nanite的细节级别和遮挡剔除方式。

Nanite本身是一种分层细节级别结构,它依赖的方法是将小三角形精简为大三角形,在差异小到无法感知时,Nanite会选择较粗糙的三角形。这在连续的表面上效果很好,但在聚合体几何体上效果不佳,从远处看时它们更像是部分不透明的云,而不是固体表面。

因此,Nanite可能认为它无法像处理常见的固体表面那样大幅度减少聚合几何体,因此,在覆盖相同数量的像素时,会绘制出更多的三角形。

还有一种优化技巧会受到聚合几何体的影响,那就是遮挡剔除。尽管遮挡剔除非常精细,但它的精细度还无法达到像素级。若几何体充满孔洞,会导致大量的过度绘制,若几何体不仅充满孔洞而且还相互重叠,那么情况会更坏,这是因为要先建立许多个深度层才能让屏幕区域遮挡住背后的内容。想象一下,屏幕上有一片8x8像素的区域,需要绘制多个深度层才能将填充所有像素。这种过度绘制就意味着,在覆盖相同数量的像素时,Nanite会尝试绘制更多的三角形,导致它的渲染速度变慢。

植被是导致遮挡剔除相关问题的一个最明显的例子,不过即便如此,这也不意味着Nanite不能应用于植被网格体。假如是充满树冠的森林,并且树冠由单独建模的树叶构成,那么Nanite的效果肯定不会很好。但将Nanite用于树干和树枝时,效果可能会好一些。若应用于建筑物表面的藤蔓,效果应该也不错,因为藤蔓与底下固体表面之间只有一层。

你可以试验一下各种用例,看看哪些适合你的项目。使用分析工具来确认Nanite在处理这些网格体时的性能情况。

紧密堆叠的表面

由于各种实际存在的限制,传统网格体的遮挡剔除使得大规模的模型搭建(kitbashing)流程几乎不可能实现。Nanite的高精细遮挡剔除可以实现使用这些类型的工作流,有助于减少开发流程中的麻烦。

正如上述"聚合几何体"小节中介绍的,导致过度绘制的一种情况是,可见表面与底部隐藏表面的距离过于接近。如果某个几何体妥当地隐藏在可见表面之下,Nanite检测并剔除它的成本是相当低的,甚至可以认为没有开销。然而,如果有一些相互堆叠的几何体,并且都位于最顶部的表面上,Nanite可能无法确定哪个位于上面或下面,导致两个几何体同时被绘制出来。

这种特殊剔除情况通常最糟糕,因为Nanite不知道哪个表面在最上层,导致绘制出所有内容。像这样的精度误差会随着屏幕尺寸和距离的变化而变化,所以,尽管10厘米的距离足够分开各个层,并且在近处看起来很好,但在更远的位置,距离差可能会小于一个像素,从而导致过度绘制。

游戏视图

大量Nanite实例紧密堆叠在一起

在下面的示例中,移动摄像机并俯视角色站立的区域,Nanite 过度绘制(Overdraw) 可视化可以显示这些堆叠的表面是如何渲染的。区域越亮,表明在该区域发生的过度绘制越多。

Nanite过度绘制可视化

过度绘制可视化能够最有效地发现过度绘制的问题。尽管一定程度的过度绘制是可以接受的,但过量会导致Nanite的剔除和光栅化开销变大,并且Nanite的缩放功能也会更加容易受到场景复杂度的影响。

面片法线和硬边法线

有个值得注意的问题是,在导入细节丰富的网格体时,因为网格体有面片法线,两个不同多边形之间的法线不平滑。此问题很常见,并且容易忽视,应该加以避免,因为网格体中顶点共享不足会导致渲染性能和数据大小的开销变得非常大。

理想情况下,一个网格体的顶点数量要少于三角形数量。如果这个比例是2:1或更高,那就可能出现问题,尤其是当三角形数量较多时。如果比例为3:1,意味着网格体完全是面状的,每个三角形都有单独的三个顶点,没有一个顶点是和其他三角形共享的。大多数情况下,这是法线不一样导致的,因为法线不平滑。

考虑到这一点,顶点越多,意味着数据越多。这也意味着顶点变换工作更多,而比率高于2:1时会陷入一些缓慢的渲染路径。在硬表面建模中专门使用不会引起任何问题,没有不用的理由。然而,若意外遇到100%面片极密集的网格体,开销要比预期的高得多。另外,要注意在其他DCC软件包中生成的密集有机型表面的导入法线,其硬法线阈值在低模网格体上可能是合理的,但在Nanite中会增加不必要的开销。

以下面的两个网格体为例,左边的网格体有面片法线,右边的网格体有平滑法线。对比使用Nanite的 三角形(Triangles) 可视化的情况,Nanite在绘制时所用的三角形数量存在明显差异。相比右边的平滑法线,左边的面片法线绘制的三角形要多得多。

使用面片法线(左)和平滑法线(右)且启用了Nanite的网格体

使用面片法线(左)和平滑法线(右)且启用了Nanite的网格体的Nanite三角形可视化

点击查看大图。

点击查看大图。

常见内容的性能

为了便于比较,我们以PlayStation 5虚幻引擎5技术演示Nanite地形中的Lumen为例,记录了以下GPU耗时信息:

  • 平均渲染分辨率为1400p,时序上采样到4K。

  • 剔除和光栅化Nanite网格体的时间约为~2.5毫秒(演示中几乎所有网格体都是Nanite网格体)

    • 几乎使用的所有几何体都是Nanite网格体

    • 几乎没有CPU开销,因为场景100%由GPU驱动

  • 计算所有Nanite网格体材质的时间约为2毫秒

    • 场景中每个材质都只产生一次绘制调用,因此CPU开销很小

将这些GPU耗时叠加后大约是4.5毫秒,相当于虚幻4中深度预通道加上基础通道的时间。这使得Nanite可用于那些以60 FPS为目标的游戏项目。

这类数据的前提是,项目不存在上文提及的各种性能不利因素。海量的实例数量以及大量的独特材质也会导致开销变大,而这也是目前Nanite的重点开发领域之一。

数据大小

Nanite能够实现大量微观细节,这可能会让人认为几何体数据会大量增加,导致玩家的游戏包大小和下载数据增加。然而,现实并没有那么可怕。事实上,Nanite的网格体格式要比标准的静态网格体格式小得多,因为Nanite有专门的网格体编码格式。

例如,对虚幻引擎5示例《古代山谷》来说,平均而言,Nanite网格体的每个输入三角形会消耗14.4字节。这意味着平均一个拥有100万三角形的Nanite网格体,在磁盘上需要约13.8兆字节(MB)。

将一个传统的低模网格体(带有法线贴图)和一个高模Nanite网格体相比较,你会看到以下效果:

低模网格体

  • 三角形:19,066

  • 顶点:10,930

  • LOD数量:4

  • Nanite:禁用

静态网格体压缩包大小:1.34MB

Nanite网格体

  • 三角形:1,545,338

  • 顶点:793,330

  • LOD数量:不适用

  • Nanite:启用

静态网格体压缩包大小:19.64MB

低模静态网格体 | 带4k法线贴图

高模静态网格体 | 带4k法线贴图

不过压缩包的大小并不代表资产的全部大小。项目中还有一些只有这个网格体会用到的特有纹理,也必须计算在内。 许多网格体使用的材质都有自己独特的纹理,包括各种法线、基础颜色、金属感、高光度、粗糙度和遮罩纹理。

这个资产只使用了两种纹理(基础颜色和法线),因此不像其他一些采用了各种独特纹理的资产那样耗费磁盘空间。 例如,注意Nanite网格体的大小(约150万个三角形)要小于4k法线贴图纹理的大小(19.64MB)。

纹理类型

纹理大小

磁盘上的大小

基础颜色(BaseColor)

4k x 4k

8.2MB

法线(Normal)

4k x 4k

21.85MB

这个网格体和它的纹理在压缩后的总包大小是:

  • 低模网格体:31.04MB

  • 高模网格体:49.69MB

由于Nanite网格体的细节已经非常丰富了,我们可以尝试用平铺细节法线贴图(与其他资产共享)来代替独特的法线贴图。虽然在这种情况下,这会导致一些品质上的损失,但损失很小,无疑比低模网格体和高模网格体之间的品质差异小得多。因此,相比一个采用4K法线贴图的低模网格体,一个由150万个三角形组成的Nanite网格体既可以看起来更美观,体积也可以更小。

启用了Nanite的网格体和纹理的压缩包总大小:27.83MB

高模静态网格体 | 带4k法线贴图

Nanite网格体 | 带4k细节法线贴图

在纹理分辨率和细节法线贴图方面可以做很多实验。这个比较是为了证明Nanite网格体的数据大小与美术师早已熟悉的数据大小没有太大区别。

最后,我们可以将Nanite压缩比作是使用高模的标准静态网格体格式,因为两者在LOD0时是相同的。

高模静态网格体

  • 三角形: 1,545,338

  • 顶点: 793,330

  • LOD数量: 4

  • Nanite: 禁用

静态网格体压缩包大小: 148.95MB

Nanite网格体

  • 三角形: 1,545,338

  • 顶点: 793,330

  • LOD数量:不适用

  • Nanite: 启用

静态网格体压缩包大小: 19.64MB

比较一下前面的Nanite压缩包,其大小为 19.64MB,比拥有4个LOD的标准静态网格体压缩包小 7.6倍

Nanite压缩和数据大小是我们关注的重点,在虚幻引擎的未来版本中会得到持续改进。

关于数据大小的通用建议

使用Nanite和虚拟纹理系统,再配合高速固态硬盘,可以减少几何体和纹理的运行时预算问题。目前最大的瓶颈是如何将此数据交付给用户。

在考虑内容交付方式时,即考虑是使用物理介质还是通过互联网下载时,磁盘上的数据大小是重要的因素,而且压缩技术能做的有限。终端用户的平均互联网带宽、光介质容量、硬盘容量等,往往落后于硬盘带宽、访问延迟、GPU算力和软件技术(例如Nanite)的发展。因此,将数据提供给客户面临挑战。

高效渲染细节丰富的网格体对于Nanite来说不是太大的问题。但在磁盘中如何保存数据,依然是一个需要改进的关键领域。

可视化模式

Nanite包含多种可视化模式来检查其在当前场景中的数据。

在关卡视口中的 查看模式(View Modes) 下拉菜单中,将鼠标悬停在 Nanite可视化(Nanite Visualization) 上,然后从选项中进行选择。

视口中的Nanite可视化菜单

例如, 概览(Overview) 可视化选项会在图像中心显示渲染后的场景,并在屏幕上显示各个Nanite可视化视图以供参考。

Nanite概览可视化

以下Nanite可视化模式可供选择:

Nanite可视化

说明

遮罩(Mask)

将Nanite几何体体标记为绿色,非Nanite几何体标记为红色。

三角形(Triangles)

显示当前场景中的Nanite网格体的所有三角形。

群集(Clusters)

显示当前场景视图中正在渲染的所有三角形分组(彩色表示)。

图元(Primitives)

将某个实例静态网格体(ISM)中所有实例的组件用同一种颜色显示。

实例(Instances)

将场景中的各个实例用不同颜色绘制。

过度绘制(Overdraw)

显示场景几何体上的过度绘制情况。紧密堆叠在一起的较小对象会比较大的对象产生更多的过度绘制。

材质复杂度(Material Complexity)

显示Nanite几何体上的材质复杂度。

材质ID(Material ID)

每个Nanite网格体的各个材质ID用单独颜色显示。

光照贴图UV(Lightmap UV)

显示Nanite网格体表面的UV坐标。

Nanite包含一个 高级(Advanced) 可视化模式,可提供 Nanite可视化(Nanite Visualization) 菜单中的更多可视化选项。这些额外的可视化功能对程序员调试或分析Nanite的各种底层内容非常有用。

此高级可视化模式可以通过控制台变量 r.Nanite.Visualize.Advanced 1 来启用。

审核Nanite内容

Nanite尚不支持虚幻引擎的某些功能,而某些功能可能永远不会受支持。Nanite工具(Nanite Tool) 使你能够在单个窗口中对支持Nanite的可用资产进行审核。你可以在内容浏览器(Content Browser)中审核资产,通过禁用或启用Nanite来查找错误或找到优化机会。

选择 工具(Tools)>Nanite工具(Nanite Tools) ,即可从主菜单打开Nanite工具(Nanite Tools)窗口。

用于审核资产的Nanite工具窗口

Nanite工具(Nanite Tools)窗口显示将导致Nanite相关错误的静态网格体。

打开Nanite工具(Nanite Tools)窗口时,有两个选项卡:

  • 错误(Errors) 选项卡将显示所有启用了Nanite且已知当前会导致Nanite相关错误的资产,例如应用了不支持Nanite的材质的资产。

  • 优化(Optimize) 选项卡将根据它们拥有的三角形数量以及是否排除使用不受支持的材质的资产,筛选项目中支持Nanite的资产。

要评估Nanite应该如何处理错误或优化,你需要对每个资产进行审核。

Nanite工具:错误

错误(Errors) 选项卡有助于快速识别在启用了Nanite的资产上应用的不受支持的材质类型。对于将项目转换为使用Nanite的项目,例如使用批量选择方法,错误(Errors)选项卡将在执行审核后显示所有不受支持的Nanite资产。

Nanite工具错误选项卡

要开始对项目中启用了Nanite的资产进行审核,请点击 执行审核(Perform Audit) 按钮。

Nanite工具执行资产审核

在审核期间,Nanite资产上启用的 材质错误(Material Errors) 项中的所有材质都将生成错误,该错误会列于资产列表中。

Nanite工具错误材质错误筛选器

Nanite网格体错误(Nanite Mesh Errors) 列表将显示全部有问题资产的名称、它拥有的三角形数量、关卡中使用的实例数量以及它产生的错误数量。

Nanite工具审核资产错误列表

你可以使用编译后的列表决定是启用Nanite,还是使用窗口右下角的 禁用Nanite(Disable Nanite) 按钮批量禁用选项。

Nanite工具窗口在选定资产上禁用Nanite

Nanite工具:优化

在三角形超出指定数量、未使用不受支持材质类型且当前未启用Nanite时,优化(Optimize) 选项卡有助于快速识别支持Nanite的资产。

Nanite工具窗口优化选项卡

在执行审核之前,如果你需要转换资产但三角形数量少于默认数量,请考虑在 几何体筛选器(Geometry Filters) 下,设置 三角形阈值(Triangle Threshold)

Nanite工具优化三角形阈值筛选器

点击 执行审核(Perform Audit) ,开始对未启用Nanite的所有资产进行项目审核。

Nanite工具优化选项卡执行资产审核

所有符合筛选器条件的非Nanite资产都会显示在 非Nanite网格体(Non-Nanite Meshes) 列表中。

非Nanite网格体的Nanite工具优化列表

你可以决定在此列表中要启用Nanite的资产,点击 启用(Enable Nanite) 即可。

Nanite工具优化在选定的网格体上启用Nanite

控制台变量和命令

你可以使用以下统计数据和控制台变量对Nanite进行调试和配置。

在运行时,你可以使用控制台变量 r.Nanite 0 来全局启用和禁用Nanite渲染。禁用Nanite能让你模拟那些不支持Nanite的平台。

Nanite回退渲染模式

当Nanite遭到禁用或平台不支持时,Nanite还提供了回退网格体渲染模式。你可以通过控制台变量 r.Nanite.ProxyRenderMode 来控制使用哪种模式。

  • 0 是默认模式,如果进行设置,就会回退为渲染回退网格体,或采用基于屏幕空间的LOD。其中包括在静态网格体编辑器(Static Mesh Editor)属性中识别 最小LOD(Min LOD) (见上方回退网格体小节所述)。

  • 1 禁用渲染所有启用了Nanite的网格体。

  • 2 与模式1类似,但允许在静态网格体编辑器(Static Mesh Editor)中通过 显示(Show)>Nanite回退(Nanite Fallback) 来渲染Nanite回退。

假如场景的实例数量非常大,远超过普通情况下的数量(即未启用Nanite时),则回退(Fallback)渲染模式1和2都很有用。这些模式使你能够在不支持Nanite的平台上用编辑器打开该场景。

例如,在虚幻引擎5的示例项目《古代山谷》中,禁用Nanite会导致产生数以万计的常规绘制调用,导致在那些不支持Nanite的平台上甚至难以打开该贴图。

Nanite统计数据命令

在控制台输入 Nanitestats 命令后,视口右上方会添加Nanite剔除统计数据的覆层。 Nanite屏上统计显示

命令参数可用于指定Nanite在屏幕上显示哪些统计信息。当没有提供参数时,将使用主视图。

Nanitestats List 会在调试输出中显示所有可用视图:

  • Primary

  • VSM_Directional

  • VSM_Perspective

  • ShadowAtlas0

  • ShadowAtlas1

  • ShadowAtlas2

需要选择某个视图时,输入该命令,后面跟上你要查看的参数。例如,输入 Nanitestats VSM_Directional 可显示其统计数据。

对于使用双通道遮挡剔除的视图,统计数据会为主通道(Main)和后通道(Post)划分单独的块。

控制Nanite流送池的大小

控制台变量 r.Nanite.Streaming.StreamingPoolSize 可用于指定使用多少内存来保存Nanite的流送数据。使用较大的内存池可以减少在场景中移动时产生的IO和解压缩工作量,但代价是内存占用较大。

如果内存池不够大,无法容纳一个视图所需的所有数据,就会发生"缓存抖动(Cache thrash)",导致即便是静态视图,流送也无法解决。

这个控制台变量无法在运行时改变,必须在配置(.ini)文件中指定。

设置单个通道的最大群集数

控制台变量 r.Nanite.MaxCandidateClustersr.Nanite.MaxVisibleClusters 可以指定单个通道中的最大候选群集数量和可见群集数量。它们的值可用于确定中间缓冲区的大小,它们的默认值已经用于常见的游戏渲染场景中。

目前没有动态调整这些缓冲区大小的机制,也无法在溢出时自动降低品质。如果这些数值过小,无法满足场景复杂度,就可能会导致渲染瑕疵,通常表现为几何体丢失或闪烁。当这类渲染瑕疵发生时,请使用 Nanitestats 来确定候选群集和可见群集的保守边界。具体而言,请查看 ClustersSWClustersHW 的统计信息。目前一个候选群集的内存开销是12字节,一个可见群集的内存开销是16字节。

这个控制台变量无法在运行时改变,必须在配置(.ini)文件中指定。