可见范围(HLOD)

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

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

  • 可见范围可以做什么以及它们在哪些场景中有用。

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

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

参见

If you only need meshes to become less detailed over distance, but don't have manually authored LOD meshes, consider relying on automatic 网格的细节级别(LOD) instead.

请注意,即使在同一个网格上,自动网格 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:起点,当相机比该值(以 3D 单位)更接近实例的原点时,实例将被隐藏。

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

  • End:结束,当相机距离实例的原点远超过此值(以 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 级别快速来回切换的情况。滞后距离(hystereis distance)由 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 Begin ,和从 House1House4Visibility 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(折射)

  • 邻近淡出

为 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(最大距离)设置为相同的值加上淡入淡出过渡距离。