はじめに
3Dゲーム開発でよくある課題として「同じメッシュを大量に描画したいけど、パフォーマンスが落ちてしまう」というものがあります。例えば、草原に数千本の草を配置する場合、そのままではDrawCallが膨大になってしまい、フレームレートが急低下してしまいます。
このような問題を解決するのがMultiMeshInstance3Dです。このノードを使うことで、同一メッシュを効率的に大量描画でき、ゲームのパフォーマンスを大きく改善できます。
MultiMeshInstance3Dとは?
MultiMeshInstance3Dは、同一のメッシュを複数のインスタンスとして効率よく描画するノードです。
たとえ: 100本の木を個別のNode3D+MeshInstance3Dで配置すると、100個のDrawCallが発生します。しかしMultiMeshInstance3Dなら、1つのDrawCallで100本すべてを描画できます。
継承ツリー:
MultiMeshInstance3D → GeometryInstance3D → VisualInstance3D → Node3D → Node
このノードを使うべき場面
- 広大な草原に数千本の草を配置したい
- 森に大量の木を配置したい
- 岩や石が散乱しているシーンを作りたい
- 群衆シーン(多数のキャラクター)のバックグラウンド表現
- パーティクル効果の代替として大量のオブジェクトを配置したい
使わない場面:
- 個別にアニメーション・移動・回転させる必要があるオブジェクト
- プレイヤーキャラクターなどの個別の制御が必要

主なプロパティと機能
| プロパティ | 型 | 説明 |
|---|---|---|
| multimesh | MultiMesh | 描画するメッシュとインスタンス情報を保持するリソース |
| mesh(MultiMesh内) | Mesh | 描画の基になるメッシュ(Mesh3D、PrismMeshなど) |
| instance_count(MultiMesh内) | int | メッシュのインスタンス数 |
| transform_format(MultiMesh内) | enum | 2D / 3D(インスタンスのtransformの次元) |
| use_colors(MultiMesh内) | bool | 各インスタンスが異なる色を持つかどうか |
基本的な使用例:
extends Node3D
func _ready():
# MultiMeshリソースを作成
var multi_mesh = MultiMesh.new()
multi_mesh.transform_format = MultiMesh.TRANSFORM_3D
multi_mesh.instance_count = 100
# メッシュを設定
var sphere_mesh = SphereMesh.new()
sphere_mesh.radius = 0.5
sphere_mesh.height = 1.0
multi_mesh.mesh = sphere_mesh
# MultiMeshInstance3Dを作成
var multi_mesh_instance = MultiMeshInstance3D.new()
multi_mesh_instance.multimesh = multi_mesh
add_child(multi_mesh_instance)
# 各インスタンスの位置をランダムに設定
for i in range(100):
var transform = Transform3D()
transform.origin = Vector3(
randf_range(-50, 50),
randf_range(-50, 50),
randf_range(-50, 50)
)
multi_mesh.set_instance_transform(i, transform)
色付きインスタンスの例:
extends Node3D
func _ready():
var multi_mesh = MultiMesh.new()
multi_mesh.transform_format = MultiMesh.TRANSFORM_3D
multi_mesh.instance_count = 50
multi_mesh.use_colors = true # 色を有効化
var box_mesh = BoxMesh.new()
multi_mesh.mesh = box_mesh
var multi_mesh_instance = MultiMeshInstance3D.new()
multi_mesh_instance.multimesh = multi_mesh
add_child(multi_mesh_instance)
# 各インスタンスの位置と色を設定
for i in range(50):
var transform = Transform3D()
transform.origin = Vector3(i * 2, 0, 0)
multi_mesh.set_instance_transform(i, transform)
# ランダムな色を設定
var random_color = Color(randf(), randf(), randf(), 1.0)
multi_mesh.set_instance_custom_data(i, random_color)

もっと使いこなす:カスタマイズできるパラメータ
まずは基本を動かしてみてから、余裕が出たら試してみてください。
| パラメータ | 説明 | 調整のポイント |
|---|---|---|
| instance_count | インスタンスの総数 | 多いほど詳細だがVRAM使用量増加。GPUメモリに注意 |
| transform_format | TRANSFORM_2D vs TRANSFORM_3D | 2D値のみなら2D形式でメモリ節約 |
| use_colors | 色情報の有効化 | ONでメモリ増加。色が不要なら OFF |
| mesh | 描画メッシュ | 複雑なメッシュはGPU負荷増加。シンプルなメッシュを推奨 |
| visibility_aabb | カリング用のAABB | 画面外のインスタンスをスキップする範囲を設定 |

まとめ
MultiMeshInstance3Dは、GPUインスタンシングの力を活用して、同一メッシュを数千個規模で効率的に描画できる強力なノードです。
- 1つのDrawCallで複数インスタンスを描画でき、パフォーマンスが大幅に向上
- Set_instance_transform()でインスタンスの位置・回転・スケールを個別設定可能
- grass/trees/rocksなど、静的オブジェクトの大量配置に最適
次回は、3D表面にテクスチャを投影して貼り付けるDecalノードを解説します。弾痕や血痕、落書きなど、ダイナミックな視覚効果を実現する手法を学んでいきましょう。
シリーズ:Godot 4 ノード解説
001〜040:各種ノード
041以降:個別ノード解説
- 041〜050: 基本的なノード群
- 051〜060: 物理・キャラクター関連
- 061〜070: パーティクル・エフェクト
- 071〜075: ライティング基礎
- 076: MultiMeshInstance3D(このページ)
- 077: Decal
- 078: FogVolume
- 079: LightmapGI
- 080: ReflectionProbe
この記事はGodot 4.xをもとに執筆しています。


コメント