程序几何

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

什么是几何?

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

什么是网格?

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

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

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

什么是网格

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

Surfaces

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

表面数组

曲面数组是一个长度为 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.

Immediate geometry (立即几何体)

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

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

有关 ImmediateGeometry 的更多信息, 请参见 ImmediateGeometry tutorial .

我应该使用哪一个?

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

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

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

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

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