介绍虚幻引擎5中的虚拟几何体系统——一种可以获得像素级细节和海量对象的系统。
UE5-Nanite官方文档
Nanite是虚幻引擎5的虚拟化几何体系统,它采用全新的内部网格体格式和渲染技术来渲染像素级别的细节以及海量对象。它可以智能地仅处理你能够感受到的细节。另外,Nanite采用高度压缩的数据格式,并且支持具有自动细节级别的细粒度流送。
流程上,Nanite允许用户先使用最高分辨率的资产来构造数字内容,然后再针对download size(云端)或者disk size(本地)来优化package的大小,而不是一开始就限制资产制作精度。
Nanite的设计与实现思路
比virtual texturing困难多了
研究了几种潜在的几何表达方式:
cluster sampling (整群抽样)
整群抽样是指整群地抽选样本单位,对被抽选的各群进行全面调查的一种抽样组织方式。例如,检验某种零件的质量时,不是逐个抽取零件,而是随机抽若干盒 (每盒装有若干个零件),对所抽各盒零件进行全面检验。如果全及总体划分为单位数目相等的R个群,用不重复抽样方法,从R群中抽取r群进行调查。
先将总体分为i个群,然后从i个群中随机抽取若干个群,对这些群内所有个体或单元均进行调查。
虚幻引擎的很多模块都需要访问传统的顶点缓冲数据(由传统方式渲染的网格体提供)。为静态网格体启用Nanite之后,将生成一个较为简单的代理网格体,以便在Nanite数据无法使用的情况下作为备选。比如在需要复杂的碰撞时,或者当平台不支持Nanite时,就会使用 代理网格体(Proxy Mesh)。如果网格体烘焙了静态光照,代理网格体也可以在Lightmass中使用。
Nanite特性
JPEG利用人眼感知的局限性,剔除掉不容易被人眼感知的部分(色彩信息),
从而节约存储空间。
Nanite网格体是一种启用了Nanite的特殊静态网格体。Nanite网格体本质上仍是三角形网格体,但对其数据进行了大量细节和压缩处理。此外,Nanite使用了一种全新系统,能以极高效的方式来渲染这种数据格式。
要让静态网格体利用Nanite,只需一个标记来启用它即可。编辑Nanite网格体的内容和传统网格体没太大不同,区别就在于相比使用传统方法渲染的几何体,Nanite能够渲染的三角形和实例要多出数个数量级。将摄像机移到足够近的位置后,Nanite就会绘制出导入的原始源三角形。
Nanite网格体支持多重UV和顶点颜色。材质可以被指定给网格体的不同分段,并且这些材质可以使用不同的着色模型和动态效果(在着色器中完成)。材质指定可以动态切换,就像其他静态网格体一样。Nanite也无需任何烘焙材质的过程。
虚拟纹理并不要求与Nanite一起使用,但非常推荐这么做。虚拟纹理是正交虚幻引擎功能,它与纹理数据的关系类似于Nanite与网格体数据的关系。
使用Nanite前,你应该首先熟悉静态网格体的工作流程,但是目前还有很多内容尚不支持。有关更多细节,请参阅本页面的支持功能小节。
Nanite可最大限度地与现有的引擎工作流无缝集成,可使用前所未有的方法来存储和渲染网格体数据。
导入期间 — 分析网格体,并将其拆分成由三角形组构成的分层群集。
渲染期间 — 根据摄像机视图以不同LOD,随时切换群集,并且可以在不破坏同一对象中相邻群集的情况下完美连接。数据会根据需求流送,因此只有可见细节才会保存在内存中。Nanite在自己的渲染通道中运行,该通道完全绕过了传统的绘制调用。你可以使用可视化模式来检视Nanite管线。
由于Nanite需要从磁盘快速流送网格体数据,因此建议使用固态硬盘(SSD)来存储运行时数据。
Nanite 遵循的设计理念是——三角形的绘制数量超过像素数量就是一种浪费。
— 摘自 UE5 Nanite 官方文档
几何体形状的复杂度提高了数个数量级,三角形和对象的实时渲染数量达到了前所未有的高度
帧预算不再会因为多边形数量、绘制调用和内存使用情况而受限
现在可以直接导入电影级品质的美术资源,例如ZBrush雕刻模型和摄影测量扫描数据
通过高模实现细节,而非将细节烘培到法线贴图纹理
节省了制作法线贴图的步骤,而且细节在VertexShader上得以更正确的显示
传统方式是要对每个几何体降低面数,再设置不同的LOD,放入引擎处理
品质损失极少或没有损失,特别是在LOD发生过渡时
数据大小
Nanite能够实现大量微观细节,这可能会让人认为几何体数据会大量增加,导致玩家的游戏包大小和下载数据增加。然而,现实并没有那么可怕。事实上,Nanite的网格体格式要比标准的静态网格体格式小得多,因为Nanite有专门的网格体编码格式。
例如,对虚幻引擎5示例《古代山谷》来说,平均而言,Nanite网格体的每个输入三角形会消耗14.4字节。这意味着平均一个拥有100万三角形的Nanite网格体,在磁盘上需要约13.8兆字节(MB)。
例如,注意Nanite网格体的大小(约150万个三角形)要小于4k法线贴图纹理的大小(19.64MB)。
聚合几何体
聚合几何体(Aggregate geometry)是指许多微小、不连贯的对象在远处被合并成单个体积(volume),例如毛发、树叶和草。这打破了原有的LOD和遮挡剔除方式。
首先,Nanite网格体本身是一种HLOD结构,它依赖的方法是将小三角形简化为大三角形;在差异小到无法感知时,Nanite会选择较粗糙的三角形。这在连续的表面上效果很好,但在聚合体(aggregate)上效果不佳——从远处看时它们更像是部分不透明的云,而不是固体类型的表面。因此,Nanite可能认为它无法像处理常见的固体表面那样大幅度减少聚合体,从而导致相同像素区域内,有更多的三角形被绘制。
会受到聚合几何体影响的第二种优化技巧是遮挡剔除(occlusion culling)。尽管遮挡剔除非常精细,但它的精细度(granularity)还无法达到像素级。充满孔洞的几何体(更糟的是多个相互重叠、充满孔洞的几何体)会导致大量的过度绘制,这是因为屏幕区域在遮挡背后的内容前,首先需要建立许多个深度层。想象一下,屏幕上有一片8x8像素的区域,在每个像素被填充之前需要绘制多个深度层。这种过度绘制就意味着,对于相同大小的像素区域,Nanite会尝试绘制更多的三角形,导致它的渲染速度变慢。
植被是一个最明显的例子;不过即便如此,这也不意味着Nanite不应用于植被网格体。假如是充满树冠的森林,并且树冠由单独建模的树叶构成,那么Nanite的效果肯定不会很好;但将Nanite用于树干和树枝时,效果可能会好一些。建筑物表面的藤曼应该效果也还不错,因为理想情况下,它与底下固体表面之前只有一层。你可以试验一下,看看哪些情况适合你的项目,并使用性能分析功能来确认Nanite在处理这些网格体时的性能情况。
由于各种实际存在的限制,传统网格体的遮挡剔除使得大规模的模型搭建(kitbashing)流程几乎不可能实现。Nanite的高精细遮挡剔除可以实现使用这些类型的工作流,有助于减少开发流程中的麻烦。
正如上述"聚合几何体"小节中介绍的,导致过度绘制的一种情况是,可见表面与底部隐藏表面的距离过于接近。如果某个几何体妥当地隐藏在可见表面之下,Nanite检测并剔除它的成本是相当低的,甚至可以认为没有开销。然而,如果有一些相互堆叠的几何体,并且都位于最顶部的表面上,Nanite可能无法确定哪个位于上面或下面,导致两个几何体同时被绘制出来。
这种特殊剔除情况通常最糟糕,因为Nanite不知道哪个表面在最上层,导致绘制出所有内容。像这样的精度误差会随着屏幕尺寸和距离的变化而变化,所以,尽管10厘米的距离足够分开各个层,并且在近处看起来很好,但在更远的位置,距离差可能会小于一个像素,从而导致过度绘制。
在下面的示例中,移动摄像机并俯视角色站立的区域,Nanite 过度绘制(Overdraw) 可视化可以显示这些堆叠的表面是如何渲染的。区域越亮,表明在该区域发生的过度绘制越多。
过度绘制可视化能够最有效地发现过度绘制的问题。尽管一定程度的过度绘制是可以接受的,但过量会导致Nanite的剔除和光栅化开销变大,并且Nanite的缩放功能也会更加容易受到场景复杂度的影响。
一般来说,能启用时应该尽量启用Nanite。启用了Nanite的静态网格体通常可以更快地渲染,占用的内存和磁盘空间会更少。
具体来说,如果网格体满足以下条件,则尤其适合使用Nanite:
包含很多三角形,或屏幕上三角形非常小
场景中有很多实例
是其他Nanite几何体的主要遮挡物
使用虚拟阴影贴图投射阴影
不过有一个例外,那就是天空球之类的对象:它的三角形在屏幕上显得很大,不会遮挡任何东西,并且场景中只有一个。通常,这种例外很少见,并且让它们启用Nanite导致的性能损失很小,所以只要Nanite支持,就不必过度担心是否应该不开启Nanite。
目前Nanite不支持某些情况。有关更多细节,请参阅本页面的支持功能小节。
以下方法可在几何体上启用Nanite(前提是几何体支持):
导入时
使用单独的网格体编辑器
在内容浏览器中的批量选择
将几何体转换为Nanite时,在每个网格体上都需要花费一些处理时间。在大型项目上,如果有很多Nanite资产,使用共享的派生数据缓存(DDC)将非常有帮助。如需更多信息,请参阅共享DDC文档。
在导入要启用Nanite的网格体时,勾选 构建Nanite(Build Nanite) 复选框。
假如不使用Lightmass预计算光照,建议禁用 生成光照贴图UV(Generate Lightmap UVs) 属性。
启用此属性后,高精度网格体会显著增加静态网格体数据的导入和构建时间。此属性还将增加一个额外的UV通道,这对于非常密集的网格体而言将会产生大量的数据。因此,如果你的项目不使用烘焙光照,则没有必要产生这两项开销。
虚幻引擎中的光照烘焙系统使用Lightmass全局光照系统在CPU或GPU上计算光照数据。使用此方法预计算光照旨在获得高质量结果,可以将信息存储在将要应用至几何体的纹理中,不受实时限制因素的影响。使用此方法,光照无法动态修改,对于那些无需改变光照效果的项目来说十分理想,对于动态光照受限的移动平台项目也是非常好的选择。
基于CPU的Lightmass 使用CPU和名为Unreal Swarm的独立进程来计算和生成光照数据。此方法可使用单个机器或将光照分配到构建场。
基于GPU的Lightmass 使用当前计算机上支持DirectX 12和光线追踪的NVIDIA GPU来计算和生成光照数据。
假如你的项目已经有了大量内容,并且你希望启用Nanite,那么有两种办法:一是使用内容浏览器批量启用资产,二是在每个资产的编辑器中单独启用。
对于你要启用Nanite的批量静态网格体资产,使用 内容浏览器(Content Browser) 选择它们,然后,右键点击 并从上下文菜单选择 Nanite > 启用(Enable) 。
打开支持Nanite的网格体的编辑器,例如静态网格体和几何体集合(Chaos物理驱动的破裂网格体),并通过 细节(Details) 面板启用Nanite。
在静态网格体编辑器(Static Mesh Editor)中,找到 Nanite设置(Nanite Settings) 并选中 启用Nanite支持(Enable Nanite Support) 复选框。
在几何体集合编辑器(Geometry Collections Editor)中,找到 Nanite 分段,并选中 启用Nanite(Enable Nanite) 复选框。
Nanite包含多种可视化模式来检查其在当前场景中的数据。
在关卡视口中的 查看模式(View Modes) 下拉菜单中,将鼠标悬停在 Nanite可视化(Nanite Visualization) 上,然后从选项中进行选择。
Nanite尚不支持虚幻引擎的某些功能,而某些功能可能永远不会受支持。Nanite工具(Nanite Tool) 使你能够在单个窗口中对支持Nanite的可用资产进行审核。你可以在内容浏览器(Content Browser)中审核资产,通过禁用或启用Nanite来查找错误或找到优化机会。
选择 工具(Tools)>Nanite工具(Nanite Tools) ,即可从主菜单打开Nanite工具(Nanite Tools)窗口。
打开Nanite工具(Nanite Tools)窗口时,有两个选项卡:
错误(Errors) 选项卡将显示所有启用了Nanite且已知当前会导致Nanite相关错误的资产,例如应用了不支持Nanite的材质的资产。
优化(Optimize) 选项卡将根据它们拥有的三角形数量以及是否排除使用不受支持的材质的资产,筛选项目中支持Nanite的资产。
要评估Nanite应该如何处理错误或优化,你需要对每个资产进行审核。