Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

程序式几何体

在 Godot 中,有许多方法可以通过程序生成几何体。在本系列教程中,我们将探讨其中的几种方法。每种技术都有自己的优点和缺点,所以最好了解每种技术,以及它在特定情况下如何发挥作用。

备注

这里描述的所有程序几何生成( procedural geometry generation )方法都在 CPU 上运行。 Godot 尚不支持在 GPU 上生成几何体。

什么是几何体?

几何体是形状的一种花式说法。在计算机图形学中,几何体通常由称为“顶点”的位置数组来表示。在 Godot 中,几何体用 Mesh(网格)来表示。

什么是网格?

Godot 中的很多东西的名称中都有“Mesh”(网格):MeshArrayMeshImmediateMeshMeshInstance3DMultiMesh、和 MultiMeshInstance3D。虽然它们都是相关的,但它们的用途略有不同。

Mesh 和 ArrayMesh 是使用 MeshInstance3D 节点绘制的资源。像 Mesh 和 ArrayMesh 这样的资源不能直接添加到场景中。MeshInstance3D 代表的是某个网格在场景中的实例。你可以在多个 MeshInstance3D 中重复使用同一个网格,用不同的材质或变换(缩放、旋转、位置等)在场景的不同部分绘制它。

如果你要多次绘制同一个对象,那么将 MultiMesh 与 MultiMeshInstance3D 结合使用会很有帮助。MultiMeshInstance3D 可以以非常低的性能成本绘制数千次网格,利用的是硬件实例化的优势。使用 MultiMeshInstance3D 的缺点是所有网格的表面都只能使用同一种材质。它使用一个实例数组为每个实例存储不同的颜色和变换,但所有实例的表面使用的都是相同的材质。

什么是网格

网格(Mesh)由一个或多个表面(Surface)组成。表面是由多个子数组组成的数组,包含顶点、法线、UV 等。通常情况下,构造表面和网格的过程对用户来说是隐藏在 RenderingServer 中的,但是通过 ArrayMesh,用户可以通过传递一个包含表面信息的数组来手动构造网格。

表面

每个表面都有自己的材质。使用 MeshInstance3D 时,你也可以使用 material_override 属性来覆盖 Mesh 中所有表面的材质。

表面数组

表面数组是一个长度为 ArrayMesh.ARRAY_MAX 的数组。数组中的每个位置都有一个子数组,包含每个顶点的信息。例如,位于 ArrayMesh.ARRAY_NORMAL 处的数组是顶点法线的 PackedVector3Array。更多信息请参阅 Mesh.ArrayType

表面数组可以是有索引的,也可以是非索引的。创建非索引数组就像在索引 ArrayMesh.ARRAY_INDEX 处不分配数组一样简单。非索引数组为每个三角形存储唯一的顶点信息,也就是说,当两个三角形共用一个顶点时,顶点在数组中是重复的。有索引的曲面数组只存储每个唯一顶点的顶点信息,然后还存储一个索引数组,它映射出如何从顶点数组构造三角形。一般来说,使用索引数组的速度更快,但这意味着你必须在三角形之间共享顶点数据,这并不总是需要的(例如,当你想要每面法线时)。

工具

Godot 提供了不同的访问和处理几何体的方法. 关于每种方法的更多信息将在下面的教程中提供.

ArrayMesh

ArrayMesh 资源扩展了 Mesh,增加了一些不同的便捷函数,最重要的是,可以通过脚本构建 Mesh 表面。

有关ArrayMesh的更多信息, 请参阅 ArrayMesh tutorial.

MeshDataTool

MeshDataTool是一个将Mesh数据转换为顶点, 面和边的数组的资源, 可以在运行时进行修改.

有关 MeshDataTool 的完整列表, 请参见 MeshDataTool tutorial.

SurfaceTool

SurfaceTool允许使用OpenGL 1.x即时模式风格的接口创建网格.

有关SurfaceTool的更多信息, 请阅读 SurfaceTool tutorial.

ImmediateMesh

ImmediateMesh 是使用立即模式风格的接口绘制对象的网格(像 SurfaceTool 一样)。ImmediateMesh 和 SurfaceTool 的区别在于,ImmediateMesh是直接用代码动态绘制的,而SurfaceTool则是用来生成一个Mesh,你可以用它做任何你想做的事。

ImmediateMesh 因为其直接的 API 而对原型设计很有用,但它的速度很慢,因为每次进行修改时都要重建几何体。它最有用的是快速添加简单的几何体来进行可视化调试(例如,通过绘制线条来可视化物理光线投射等)。

有关 ImmediateMesh的更多信息,请参见 ImmediateMesh 教程

我应该使用哪一个?

用哪种方法取决于你想做什么,以及你觉得什么样的做法用起来更舒服。

SurfaceTool和ArrayMesh都是生成不随时间变化的静态几何体(网格)的绝佳工具.

使用 ArrayMesh 比使用 SurfaceTool 稍快一些,但 API 的难度更大一些。另外,SurfaceTool 还有一些便捷的方法,比如 generate_normals()index()

ImmediateMesh 比 ArrayMesh 和 SurfaceTool 受到更多限制。但是,如果你本来就需要每一帧都改变几何体,它提供的接口更简单,甚至可能比每一帧生成一个 ArrayMesh 更快。

MeshDataTool 的速度并不快,但它可以让你访问网格的各种属性,而这些属性是其他工具无法获得的(边、面等)。当你需要根据这类数据来变换网格时,它是非常有用的,但如果不需要这些信息,就不适合使用。如果你要使用需要访问面数组或边数组的算法,最好使用 MeshDataTool。