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.

使用 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()

上述程式碼會在每個影格動態建立並繪製一個表面。