Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

可见范围(HLOD)

网格的细节级别(LOD)遮挡剔除一起,可见范围是另一种用于提升大型复杂 3D 场景性能的工具。

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

  • 可见范围的作用及其适用场景。

  • 如何在 Godot 中设置可见范围(手动 LOD)。

  • 如何调整可见范围以获得最佳性能和质量。

参见

如果你只是希望网格在距离变远时细节自动降低,但手头又没有手动制作的 LOD 网格,那么可以考虑直接使用自动 网格的细节级别(LOD) 功能。

请注意,自动网格 LOD 和可见范围可以同时使用,哪怕是在同一个网格上。

工作原理

可见范围可用于任何继承自 GeometryInstance3D 的节点。这意味着它们不仅可以与 MeshInstance3D 和 MultiMeshInstance3D 一起使用以实现由美术师控制的 HLOD,还可以与 GPUParticles3D、CPUParticles3D、Label3D、Sprite3D、AnimatedSprite3D 和 CSGShape3D 一起使用。

由于可见范围是按每个节点单独配置的,因此可以将不同的节点类型用作 LOD 系统的一部分。例如,你可以在近距离时显示代表一棵树的 MeshInstance3D,并在远处将其替换为 Sprite3D 顶替物以提高性能。

HLOD 相比传统 LOD 系统的优势在于其层次化特性。单个较大的网格可以替换多个较小的网格,从而减少远处的绘制调用次数,同时在近距离时保留剔除机会。例如,你可以设置一组房屋,在近距离时使用单独的 MeshInstance3D 节点(每个房屋一个),而在远处则合并为单个 MeshInstance3D 来表示细节较少的房屋组(或使用 MultiMeshInstance3D)。

最后,当相机距离物体太近或太远时,可见范围也可用于让某些对象完全淡入淡出。这既可以用于游戏性目的,也可以用来减少视觉杂乱。例如,当 Label3D 节点距离玩家太远而无法阅读或与玩家无关时,可以使用可见范围将其淡出。

设置可见范围

这是配置基本 LOD 系统的快速入门指南。按照本指南设置后,该 LOD 系统将在近距离时显示 SphereMesh,当相机足够远时显示 BoxMesh。还可以通过 Begin Margin(起始边距)和 End Margin(结束边距)属性配置较小的滞后边距(hysteresis margin)。这可以防止相机在 LOD 过渡的“边缘”移动时,LOD 过快来回切换。

选中 MeshInstance3D 节点后,可以在 GeometryInstance3D 检查器的 Visibility Range (可见范围)部分中找到可见范围属性。

  • 添加一个 Node3D 节点,用于将两个 MeshInstance3D 节点分组到一起。

  • 添加第一个 MeshInstance3D 节点作为 Node3D 的子节点。将一个新的 SphereMesh 分配给其 Mesh 属性。

  • 将第一个 MeshInstance3D 的可见范围 End 设置为 10.0,将 End Margin 设置为 1.0

  • 添加第二个 MeshInstance3D 节点作为 Node3D 的子节点。将一个新的 BoxMesh 分配给其 Mesh 属性。

  • 将第二个 MeshInstance3D 的可见范围 Begin 设置为 10.0,将 Begin Margin 设置为 1.0

  • 将相机移远再移近物体。注意当相机移远时,对象如何从球体(SphereMesh)过渡到盒子(BoxMesh)。

可见范围属性

在任何继承自 GeometryInstance3D 的节点的检查器中,你都可以在 GeometryInstance3D 的 Visibility Range (可见范围)部分中调整以下属性:

  • Begin:开始。当相机距离实例 AABB(轴对齐边界框)的中心比此值(以 3D 单位计)更近时,实例将被隐藏。

  • Begin Margin:起始边距。用于近距离过渡的滞后(hysteresis)或 Alpha 淡入淡出过渡距离(以 3D 单位计)。该属性的行为取决于 Fade Mode(淡入淡出模式)。

  • End:结束。当相机距离实例 AABB(轴对齐边界框)的中心比此值(以 3D 单位计)更远时,实例将被隐藏。

  • End Margin:结束边距。用于远距离过渡的滞后或 Alpha 淡入淡出过渡距离(以 3D 单位计)。该属性的行为取决于 Fade Mode(淡入淡出模式)。

  • Fade Mode:淡入淡出模式。控制如何在 LOD 级别之间进行过渡。详见下文。

淡入淡出模式

备注

只有当 Visibility Range > Begin MarginVisibility Range > End Margin 大于 0.0 时,所选的淡入淡出模式才会产生可见效果。

在检查器的 Visibility Range(可见范围)部分中,有 3 种淡入淡出模式可供选择:

  • Disabled:禁用。使用滞后(hysteresis)在 LOD 级别之间即时切换。这可以防止玩家在 LOD 过渡点前后移动时,LOD 级别快速来回切换的情况。滞后距离由 Visibility Range > Begin MarginVisibility Range > End Margin 确定。该模式提供最佳性能,因为它不会强制渲染在淡入淡出过渡期间变为透明。

  • Self:自身。使用 Alpha 混合在 LOD 级别之间平滑淡入淡出。当达到其自身可见范围的极限时,节点将自行淡出。淡入淡出过渡距离由 Visibility Range > Begin MarginVisibility Range > End Margin 确定。该模式在淡入淡出过渡期间强制对对象进行透明渲染,因此会对性能产生影响。

  • Dependencies:依赖项。使用 Alpha 混合在 LOD 级别之间平滑淡入淡出。当达到其自身可见范围的极限时,节点将淡入其依赖项。淡入淡出过渡距离由 Visibility Range > Begin MarginVisibility Range > End Margin 确定。该模式在淡入淡出过渡期间强制对对象进行透明渲染,因此会对性能产生影响。该模式旨在用于使用可见性父级的分层 LOD 系统。如果可见范围用于非分层 LOD,则它的作用与 Self 相同。

可见性父级

Visibility Parent(可见性父级)属性让设置 HLOD 变得更加容易。如果父节点在其当前可见范围属性下可见,子节点将自动隐藏。

备注

Visibility Parent 的目标必须继承自 GeometryInstance3D

尽管名称如此,Visibility Parent 属性可以指向场景树中不是该节点父节点的节点。但是,无法将 Visibility Parent 指向子节点,因为这会创建不受支持的依赖循环。如果发生依赖循环,你将在“输出”面板中看到一条错误消息。

给定以下场景树(其中所有节点都继承自 GeometryInstance3D):

┖╴BatchOfHouses
    ┠╴House1
    ┠╴House2
    ┠╴House3
    ┖╴House4

在该示例中, BatchOfHouses 是一个大型网格,用于在远距离观察时代表所有子节点。House1House4 是代表各个房屋的较小 MeshInstance3D。要在此示例中配置 HLOD,我们只需配置两项:

  • Visibility Range Begin 设置为大于 0.0 的数值,使 BatchOfHouses 仅在距离相机足够远时出现。在此距离内,我们则希望显示 House1House4

  • House1House4 上,将 Visibility Parent 属性指定为 BatchOfHouses

这样更容易进行进一步调整,因为你无需同时调整 BatchOfHousesVisibility Range BeginHouse1House4Visibility Range End

淡入淡出模式由 Visibility Parent 属性自动处理,因此只有在父节点完全淡出后,子节点才会被隐藏。这样做是为了尽量减少可见的跳变。根据你的 HLOD 设置,你可能需要尝试 SelfDependencies 淡入淡出模式

备注

通过 Visible 属性隐藏的节点,本质上是从可见性依赖树中移除的,因此依赖实例不会考虑隐藏节点或其祖先节点。

实际上,这意味着如果通过将其 Visibility Parent 节点的 Visible 属性设置为 false 来隐藏该节点的目标,则该节点将不会根据可见性父级中指定的 Visibility Range Begin 值进行隐藏。

配置建议

在远处使用更简单的材质以提高性能

进一步提高性能的一种方法是为远处的 LOD 网格使用更简单的材质。虽然使用 LOD 网格会减少需要渲染的顶点数量,但材质的每像素着色负载保持不变。然而,在复杂的 3D 场景中,每像素着色负载通常就是 GPU 的瓶颈。减少 GPU 着色负载的一种方法是在不会产生太大视觉差异时使用更简单的材质。

这样做时应仔细衡量性能增益,因为增加场景中独特材质的数量本身就会产生性能开销。尽管如此,为远处的 LOD 网格使用更简单的材质仍然可能带来净性能增益,因为每像素所需的计算更少。

例如,在远处的 LOD 网格使用的材质上,可以禁用开销较高的材质功能,如:

  • 法线贴图(尤其是在移动平台上)

  • Rim(边缘)

  • Clearcoat(清漆)

  • Anisotropy(各向异性)

  • Height(高度)

  • Subsurface Scattering(次表面散射)

  • Back Lighting(背光照明)

  • Refraction(折射)

  • Proximity Fade(邻近淡出)

为 LOD 过渡使用抖动

Godot 目前仅支持基于 Alpha 的可见范围淡入淡出。不过,你可以为不同的 LOD 级别使用多种不同的材质来实现抖动效果。

对于 LOD 过渡,使用抖动而非 Alpha 混合有两个优点:

  • 性能更高,因为与 Alpha 混合相比,抖动透明度的渲染速度更快。

  • 在 LOD 过渡期间,不会因透明度排序问题而出现视觉故障。

抖动的缺点是,在 LOD 淡入淡出过渡期间可以看到“嘈杂”的图案。在更高的视口分辨率或启用时间抗锯齿时,这可能不那么明显。

此外,由于 BaseMaterial3D 中的距离淡入淡出仅支持近距离 远距离淡入淡出,因此该设置最好仅与两个 LOD 一起使用。

  • 确保两个 MeshInstance3D 节点上的 Begin MarginEnd Margin 都设置为 0.0,因为此处不需要滞后或 Alpha 淡入淡出。

  • 在两个 MeshInstance3D 节点上,按所需的淡入淡出过渡距离减小 Begin增加 End 相同的距离。这是抖动过渡真正可见所必需的。

  • 在近距离显示的 MeshInstance3D 上,在检查器中编辑其材质。将其 Distance Fade(距离淡出)模式设置为 Object Dither(对象抖动)。将 Min Distance(最小距离)设置为与可见范围 End 相同的值。将 Max Distance(最大距离)设置为相同的值减去淡入淡出过渡距离的差值。

  • 在远处显示的 MeshInstance3D 上,在检查器中编辑其材质。将其 Distance Fade(距离淡出)模式设置为 Object Dither(对象抖动)。将 Min Distance(最小距离)设置为与可见范围 Begin 相同的值。将 Max Distance(最大距离)设置为相同的值加上淡入淡出过渡距离的总和 。