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 を使用して動的なジオメトリを作成するための便利なツールです。これはフレームごとに更新する必要があるメッシュに対して使いやすく効率的です。

このノードを使用して複雑なジオメトリ(数千個の頂点)を生成することは、たとえ1回だけ実行される場合でも非効率的です。これはフレームごとに変化する単純なジオメトリを生成するように設計されています。

まず MeshInstance3D を作成し、インスペクターでそれに ImmediateMesh を追加する必要があります。

次に MeshInstance3D にスクリプトを追加します。ImmediateMesh のコードは、各フレームを更新する場合は _process() 関数に、メッシュを1回だけ作成して更新しない場合は _ready() 関数に記述する必要があります。サーフェスを1回だけ生成する場合、ImmediateMesh は、生成されたメッシュがキャッシュされて再利用されるため、他の種類のメッシュと同じくらい効率的です。

ジオメトリの生成を開始するには、 surface_begin() を呼び出す必要があります。 surface_begin()PrimitiveType を引数として 取ります。 PrimitiveType は、三角形、線、点など、指定された頂点に基づいてプリミティブを配置する方法を GPU に指示します。完全なリストは、Mesh クラスのリファレンス ページにあります。

surface_begin() を呼び出したら、頂点の追加を開始する準備が整います。頂点は一度に1つずつ追加します。最初に 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_add_vertex() を呼び出す前に属性を2回追加した場合、2回目の呼び出しのみが使用されます。

最後にすべての頂点を追加したら、サーフェスの生成が完了したことを通知するために surface_end() を呼び出します。メッシュの複数のサーフェスを生成するには、 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()

上記のコードは、フレームごとに1つのサーフェスを動的に作成して描画します。