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.

程序式几何体

There are many ways to procedurally generate geometry in Godot. In this tutorial series, we will explore a few of them. Each technique has its own benefits and drawbacks, so it is best to understand each one and how it can be useful in a given situation.

备注

All the procedural geometry generation methods described here run on the CPU. Godot doesn't support generating geometry on the GPU yet.

什么是几何体?

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

什么是网格?

Many things in Godot have mesh in their name: the Mesh, the ArrayMesh, the MeshInstance3D, the MultiMesh, and the MultiMeshInstance3D. While they are all related, they have slightly different uses.

Meshes and ArrayMeshes are resources that are drawn using a MeshInstance3D node. Resources like Meshes and ArrayMeshes cannot be added to the scene directly. A MeshInstance3D represents one instance of a mesh in your scene. You can reuse a single mesh in multiple MeshInstance3Ds to draw it in different parts of your scene with different materials or transformations (scale, rotation, position etc.).

If you are going to draw the same object many times, it can be helpful to use a MultiMesh with a MultiMeshInstance3D. MultiMeshInstance3Ds draw meshes thousands of times very cheaply by taking advantage of hardware instancing. The drawback with using a MultiMeshInstance3D 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.

什么是网格

A Mesh is composed of one or more surfaces. A surface is an array composed of multiple sub-arrays containing vertices, normals, UVs, etc. Normally the process of constructing surfaces and meshes is hidden from the user in the RenderingServer, but with ArrayMeshes, the user can construct a Mesh manually by passing in an array containing the surface information.

表面

Each surface has its own material. Alternatively, you can override the material for all surfaces in the Mesh when you use a MeshInstance3D 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 PackedVector3Array of vertex normals. See Mesh.ArrayType for more information.

表面数组可以是有索引的,也可以是非索引的。创建非索引数组就像在索引 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 is a node that uses an immediate mode style interface (like SurfaceTool) to draw objects. The difference between ImmediateMesh and the SurfaceTool is that ImmediateMesh 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 MeshInstance3D to be seen.

ImmediateMesh 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.).

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

我应该使用哪一个?

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

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

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

ImmediateMesh regenerates the mesh every frame, so it is much slower than ArrayMesh or SurfaceTool. However, if you need the geometry to change every frame anyway, it provides a much easier interface that may even be a little faster than generating an ArrayMesh every frame.

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