程序几何

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

What is geometry?

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

What is a Mesh?

在Godot中,很多东西的名字中都有mesh: MeshArrayMeshMeshInstanceMultiMeshMultiMeshInstance 。虽然它们都是相关的,但用途略有不同。

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

如果你要多次绘制同一个对象,那么使用MultiMesh与MultiMeshInstance会很有帮助。MultiMeshInstance可以非常便宜地绘制数千次网格。它利用了硬件实例的优势来实现这一目的。使用MultiMeshInstance的缺点是所有实例只能使用一种材料。它使用一个实例数组为每个实例存储不同的颜色和变换,但所有的实例都使用相同的材质。

What a Mesh is

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

Surfaces

每个曲面都有自己的材质。另外,当你使用MeshInstance时,你可以使用 MeshInstance.override_material 覆盖Mesh中所有曲面的材质。

Surface array

曲面数组是一个长度为 ArrayMesh.ARRAY_MAX 的数组。数组中的每个位置都有一个子数组,包含每个顶点的信息。例如,位于 ArrayMesh.ARRAY_NORMAL 处的数组是一个 PoolVector3Array 的顶点法线。

曲面数组可以是有索引的,也可以是非索引的。创建非索引数组就像在索引``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

ImmediateGeometry

ImmediateGeometry是一个使用即时模式风格接口(像SurfaceTool一样)绘制对象的节点。ImmediateGeometry和SurfaceTool的区别在于,ImperialGeometry本身是一个节点,可以添加到场景树中,直接从代码中绘制。SurfaceTool生成一个Mesh,需要添加一个MeshInstance才能看到。

ImmediateGeometry因为其直接的API而对原型设计很有用,但它的速度很慢,因为每一帧都要重建几何体。它最有用的是快速添加简单的几何体来进行可视化调试(例如,通过画线来可视化物理学射线广播等)。

For more information about ImmediateGeometry, please see the ImmediateGeometry tutorial.

Which one should I use?

用哪种方法取决于你想做什么,以及你能接受什么样的程序。

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

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

ImmediateGeometry 每一帧都会重新生成网格,所以它比 ArrayMesh 或 SurfaceTool 慢很多。然而,如果你需要每一帧都改变几何体,它提供了一个更简单的接口,甚至可能比每一帧生成一个ArrayMesh更快。

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