网格的细节级别(LOD)

遮挡剔除 一样,细节级别(LOD)是优化 3D 项目渲染性能的最重要方法之一。

你会在这个页面中学习到:

  • 网格 LOD 如何提高 3D 项目的渲染性能。

  • 如何在 Godot 中设置网格 LOD。

  • 如何衡量网格 LOD 在项目中的效果(如果达不到预期效果,还可以探索其他方法)。

参见

你可以通过遮挡剔除与网格 LOD 演示项目观察到网格 LOD 的工作原理。

前言

从历史上看,3D 游戏中的细节层次包括手动绘制几何密度较低的网格,然后配置距离阈值,在距离阈值上绘制这些细节较低的网格。如今,当需要加强控制时,这种方法仍在使用。

然而,在拥有大量详细 3D 资产的项目中,手动设置 LOD 可能是一个非常耗时的过程。因此,自动网格细分和 LOD 配置越来越受欢迎。

Godot 提供了一种方法,可以在导入时自动生成细节较少的网格供 LOD 使用,然后在需要时自动使用这些 LOD 网格。这对用户完全透明。meshoptimizer 库用于幕后的 LOD 网格生成。

网格 LOD 适用于任何绘制 3D 网格的节点。这包括 MeshInstance3D、MultiMeshInstance3D、GPUParticles3D 和 CPUParticles3D。

视觉比较

以下是导入时生成 LOD 网格的示例。当摄像机远离物体时,将使用细节较少的网格:

从最详细(左)到最不详细(右),阴影视图

从最详细(左)到最不详细(右),阴影视图

这是使用线框渲染的同一张图像,以使细分更容易被看到:

从最详细(左)到最不详细(右),线框视图

从最详细(左)到最不详细(右),线框视图

参见

如果你需要使用艺术家创建的网格手动配置细节层次,请使用 可见范围(HLOD) 而不是自动网格 LOD。

生成网格 LOD

默认情况下,导入的 3D 场景(glTF、.blend、Collada、FBX)会自动生成网格 LOD。生成 LOD 网格后,将在渲染场景时自动使用它们。你无需手动配置任何内容。

然而,对于导入的 3D 网格(OBJ),网格LOD生成 不会 自动启动。这是因为 OBJ 文件默认情况下不作为完整的 3D 场景导入,而仅作为单独的网格资源加载到MeshInstance3D 节点(或 GPUParticle3D,CPUParticles3D…)。

为了使OBJ文件具有为其生成的网格LOD,在文件系统面板中选择它,去到导入面板,将其 导入为 选项更改为 场景 ,然后单击 重新导入

更改导入面板中 OBJ 文件的导入类型

更改导入面板中 OBJ 文件的导入类型

这需要在单击 重新导入 后重新启动编辑器。

备注

网格 LOD 生成过程并不完美,偶尔可能会出现渲染问题(尤其是在蒙皮网格中)。在复杂网格上生成网格 LOD 也可能需要一段时间。

如果网格 LOD 导致特定网格看起来已被损坏,则可以在导入面板中禁用该网格的 LOD 生成。这也将加快资源导入的速度。这可以在 3D 场景的导入选项中全局执行,也可以使用“高级导入设置”对话框在逐个网格完成。

详见导入 3D 场景

比较网格 LOD 视觉效果和性能

要在编辑器中禁用网格 LOD 以进行比较,请使用 禁用网格 LOD 高级调试绘制模式。这可以使用 3D 视口左上角的菜单来完成(标记为 透视正交 ,具体取决于相机模式):

在 3D 视口左上角的菜单中禁用网格 LOD

在 3D 视口左上角的菜单中禁用网格 LOD

在同一菜单中启用 查看帧时间 以查看右上角的 FPS。同时在同一菜单中启用 查看信息 ,以查看右下角渲染的图元(顶点+索引)的数量。

如果网格 LOD 在场景中正常工作,并且摄影机离网格足够远时,你应注意到,当网格 LOD 处于启用状态时,绘制的图元数量会减少,而 FPS 会增加(除非遭遇 CPU 瓶颈)。

若要查看网格 LOD 抽取的操作,请在上面指定的菜单中将调试绘制模式更改为 显示线框 ,然后调整 渲染 > 网格 LOD > LOD 更改 > 阈值像素 项目设置。

配置网格 LOD 性能和质量

你可以通过更改 渲染 > 网格 LOD > LOD 更改 > 阈值像素 项目设置来调整根视口中网格 LOD 转换的变化程度。要在运行时更改此值,请在根视口上设置 Mesh_LOD_Threshold,如下所示:

  1. get_tree().root.mesh_lod_threshold = 4.0

每个视口都有自己的 mesh_lod_threshold 属性,可以独立于其他视口进行设置。

默认网格 LOD 阈值 1 像素经过调整,看起来 感知上 无损;它提供了显着的性能提升,但质量却有不明显的损失。 当相机移开时,较高的值将使 LOD 过渡更快发生,从而导致更高的性能但质量较低。

如果需要对网格 LOD 执行逐对象调整,则可以通过调整从 GeometryInstance3D 继承的任何节点上的 LOD Bias 属性来调整 LOD 过渡的激进程度。高于 1.0 的值将使 LOD 转换发生得比通常晚(导致更高质量但更低的性能)。低于 1.0 的值将使 LOD 转换比通常更快发生(导致更低的质量但更高的性能)。

此外,ReflectionProbe 节点具有自己的 Mesh LOD Threshold 属性,当反射探针更新时,可以调整该属性以提高渲染性能。这对于使用 Always 更新模式的 ReflectionProbe 尤为重要。

备注

渲染场景时,网格 LOD 会选择使用屏幕空间标尺。这意味着它会自动考虑相机视野和视口分辨率。更高的摄像机 FOV 和更低的视口分辨率将使 LOD 选择更加激进;当相机移开时,引擎将更早地显示严重破坏的模型。

因此,与 可见范围(HLOD) 不同,你无需在项目中执行任何特定操作,即可考虑相机 FOV 和视口分辨率。

将网格 LOD 与 MultiMesh 和粒子结合使用

对于 LOD 选择,节点的 AABB 最接近相机的点被用作基础。这适用于任何类型的网格 LOD(包括单个 MeshInstance3D),但对于同时显示多个网格的节点(例如 MultiMeshInstance3D、GPUParticles3D 和 GPUParticles3D)有一些影响。最重要的是,这意味着在给定时间所有实例都将使用相同的 LOD 级别进行绘制。

如果你发现 GPUParticles3D 的 LOD 选择不正确,请确保通过选择 GPUParticles3D 节点并使用 3D 视口顶部的 GPUParticles3D > 生成 AABB 来配置节点的可见性 AABB。

如果 MultiMesh 中的实例彼此距离较远,则应将它们放置在单独的 MultiMeshInstance3D 节点中。这样做还可以提高渲染性能,因为视锥体和遮挡剔除将能够剔除单个节点(尽管它们无法剔除 MultiMesh 中的单个实例)。