程序式几何体

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

什么是几何体?

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

什么是网格?

在 Godot 中,很多东西的名字中都带“Mesh”(网格):MeshArrayMeshMeshInstanceMultiMeshMultiMeshInstance。虽然它们都是相关的,但用途略有不同。

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

If you are going to draw the same object many times, it can be helpful to use a MultiMesh with a MultiMeshInstance. MultiMeshInstances draw meshes thousands of times very cheaply by taking advantage of hardware instancing. The drawback with using a MultiMeshInstance is that each of your mesh’s surfaces are limited to one material for all instances. It uses an instance array to store different colors and transformations for each instance, but all the instances of each surface use the same material.

什么是网格

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

表面

Each surface has its own material. Alternatively, you can override the material for all surfaces in the Mesh when you use a MeshInstance using the material_override property.

表面数组

The surface array is an array of length ArrayMesh.ARRAY_MAX. Each position in the array is filled with a sub-array containing per-vertex information. For example, the array located at ArrayMesh.ARRAY_NORMAL is a PoolVector3Array of vertex normals. See Mesh.ArrayType for more information.

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

工具

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

ArrayMesh

The ArrayMesh resource extends Mesh to add a few different quality of life functions and, most importantly, the ability to construct a Mesh surface through scripting.

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

MeshDataTool

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

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

SurfaceTool

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

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

ImmediateGeometry

ImmediateGeometry is a node that uses an immediate mode style interface (like SurfaceTool) to draw objects. The difference between ImmediateGeometry and the SurfaceTool is that ImmediateGeometry is a node itself that can be added to the scene tree and is drawn directly from the code, while the SurfaceTool generates a Mesh that needs to be added to a MeshInstance to be seen.

ImmediateGeometry is useful for prototyping because of its straightforward API, but it is slow because the geometry is rebuilt every frame. It is most useful for adding simple geometry for visual debugging (e.g. by drawing lines to visualize physics raycasts etc.).

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

我应该使用哪一个?

Which approach you use depends on what you are trying to do and what kind of procedure you are comfortable with.

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

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

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

The MeshDataTool is not fast, but it gives you access to all kinds of properties of the mesh that you don’t get with the others (edges, faces, etc.). It is incredibly useful when you need that sort of data to transform the mesh, but it is not a good idea to use it if that extra information is not needed. The MeshDataTool is best used if you are going to be using an algorithm that requires access to the face or edge array.