使用 ImmediateMesh
ImmediateMesh 是一個方便的工具,可以用 OpenGL 1.x 風格的 API 建立動態幾何體。這讓它適合用於需要每影格即時更新的網格,且易於使用。
使用這個工具產生複雜幾何體(數千個頂點)效率不高,即使只產生一次也是如此。ImmediateMesh 的設計目標是用來生成每影格變化的簡單幾何體。
首先,你需要在編輯器中建立一個 MeshInstance3D,並在屬性檢視器中將 ImmediateMesh 指派給它。
接著,將腳本掛到 MeshInstance3D 上。如果要每影格即時更新,請將 ImmediateMesh 的程式碼寫在 _process()。若只需建立一次網格且不會更新,則可寫在 _ready()。若只產生一次表面,ImmediateMesh 的效能與其他網格類型相同,因為生成後會快取重複利用。
要開始生成幾何體,必須先呼叫 surface_begin()。surface_begin() 需要一個 PrimitiveType 參數,這是用來指示 GPU 如何根據給定頂點組合出三角形、線段、點等。所有可用的型別都可以在 Mesh 類別參考頁找到。
呼叫 surface_begin() 之後,就可以開始逐一新增頂點。首先,透過 surface_set_****()``(如 ``surface_set_normal())指定頂點的屬性(如法線或 UV),然後用 surface_add_vertex() 將該頂點加入網格。範例如下:
# Add a vertex with normal and uv.
surface_set_normal(Vector3(0, 1, 0))
surface_set_uv(Vector2(1, 1))
surface_add_vertex(Vector3(0, 0, 1))
只有在呼叫 surface_add_vertex() 之前設定的屬性,才會包含在該頂點中。若重複設定同一屬性,僅最後一次設定會生效。
最後,當加入所有頂點後,請呼叫 surface_end(),通知 Godot 你已完成該表面。你也可以多次呼叫 surface_begin() 和 surface_end(),以建立多個表面。
以下範例會在 _ready() 函式中繪製一個三角形。
extends MeshInstance3D
func _ready():
# Begin draw.
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
# Prepare attributes for add_vertex.
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(0, 0))
# Call last for each vertex, adds the above attributes.
mesh.surface_add_vertex(Vector3(-1, -1, 0))
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(0, 1))
mesh.surface_add_vertex(Vector3(-1, 1, 0))
mesh.surface_set_normal(Vector3(0, 0, 1))
mesh.surface_set_uv(Vector2(1, 1))
mesh.surface_add_vertex(Vector3(1, 1, 0))
# End drawing.
mesh.surface_end()
ImmediateMesh 也可以跨影格使用。每次呼叫 surface_begin() 和 surface_end(),都會新增一個新表面到 ImmediateMesh。如果你想每影格都從零重新建立網格,請在呼叫 surface_begin() 之前先呼叫 clear_surfaces()。
extends MeshInstance3D
func _process(delta):
# Clean up before drawing.
mesh.clear_surfaces()
# Begin draw.
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
# Draw mesh.
# End drawing.
mesh.surface_end()
上述程式碼會在每個影格動態建立並繪製一個表面。