Up to date

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

程式式幾何體

在 Godot 中,有許多方法可以通過程式生成幾何體。在本系列教學中,我們將探討其中的幾種方法。每種技術都有自己的優點和缺點,所以最好瞭解每種技術,以及它在特定情況下如何發揮作用。

備註

這裡描述的所有程式幾何生成方法都在 CPU 上運作。 Godot 尚未支援在 GPU 上產生幾何體。

什麼是幾何體?

幾何體是形狀的一種花式說法。在電腦圖形學中,幾何體通常由稱為“頂點”的位置陣列來表示。在 Godot 中,幾何體用 Mesh(網格)來表示。

什麼是網格?

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

Mesh 和 ArrayMesh 是使用 MeshInstance 節點繪製的資源。像 Mesh 和 ArrayMesh 這樣的資源不能直接新增到場景中。MeshInstance 代表的是某個網格在場景中的實例。您可以在多個 MeshInstance 中重複使用同一個網格,用不同的材質或變換(縮放、旋轉、位置等)在場景的不同部分繪製它。

如果你要多次繪製同一個物件,那麼使用 MultiMesh 與 MultiMeshInstance 就會很有幫助。MultiMeshInstance 可以非常便宜地繪製數千次網格,利用的是硬體產生實體的優勢。使用 MultiMeshInstance 的缺點是所有實例都只能使用同一種材質。它使用一個實例陣列為每個實例儲存不同的顏色和變換,但所有實例的表面使用的都是相同的材質。

什麼是網格

網格(Mesh)由一個或多個表面(Surface)組成。表面是由多個子陣列組成的陣列,包含頂點、法線、UV 等。通常情況下,建構表面和網格的過程對使用者來說是隱藏在 VisualServer 中的,但是通過 ArrayMesh,使用者可以通過傳遞一個包含表面資訊的陣列來手動建構網格。

表面

每個表面都有自己的材質。使用 MeshInstance 時,你也可以使用 material_override 屬性來覆蓋 Mesh 中所有表面的材質。

表面陣列

表面陣列是一個長度為 ArrayMesh.ARRAY_MAX 的陣列。陣列中的每個位置都有一個子陣列,包含每個頂點的資訊。例如,位於 ArrayMesh.ARRAY_NORMAL 處的陣列是頂點法線的 PoolVector3Array。更多資訊請參閱 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 is a mesh that uses an immediate mode style interface (like SurfaceTool) to draw objects. The difference between ImmediateMesh and the SurfaceTool is that ImmediateMesh is drawn directly with code dynamically, while the SurfaceTool is used to generated a Mesh that you can do whatever you want with.

ImmediateMesh is useful for prototyping because of its straightforward API, but it is slow because the geometry is rebuilt each time you make a change. It is most useful for adding simple geometry for visual debugging (e.g. by drawing lines to visualize physics raycasts etc.).

有關 ImmediateGeometry 的更多資訊,請參見 ImmediateGeometry 教學

GDScript是什麼?為什麼我要用它?

用哪種方法取決於你想做什麼,以及你覺得什麼樣的做法用起來更舒服。

SurfaceTool和ArrayMesh都是生成不隨時間變化的靜態幾何體(網格)的絕佳工具.

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

ImmediateMesh is more limited than both ArrayMesh and SurfaceTool. However, if you need the geometry to change every frame anyway, it provides a much easier interface that can be slightly faster than generating an ArrayMesh every frame.

MeshDataTool 的速度並不快,但它可以讓你存取網格的各種屬性,而這些屬性是其他工具無法獲得的(邊、面等)。當你需要根據這類資料來變換網格時,它是非常有用的,但如果不需要這些資訊,就不適合使用。如果您要使用需要存取面陣列或邊陣列的演算法,最好使用 MeshDataTool。