Godot入門:MultiMeshInstance3Dの使い方と活用法

はじめに

3Dゲーム開発でよくある課題として「同じメッシュを大量に描画したいけど、パフォーマンスが落ちてしまう」というものがあります。例えば、草原に数千本の草を配置する場合、そのままではDrawCallが膨大になってしまい、フレームレートが急低下してしまいます。

このような問題を解決するのがMultiMeshInstance3Dです。このノードを使うことで、同一メッシュを効率的に大量描画でき、ゲームのパフォーマンスを大きく改善できます。

MultiMeshInstance3Dとは?

MultiMeshInstance3Dは、同一のメッシュを複数のインスタンスとして効率よく描画するノードです。

たとえ: 100本の木を個別のNode3D+MeshInstance3Dで配置すると、100個のDrawCallが発生します。しかしMultiMeshInstance3Dなら、1つのDrawCallで100本すべてを描画できます。

継承ツリー:

MultiMeshInstance3D → GeometryInstance3D → VisualInstance3D → Node3D → Node

このノードを使うべき場面

  • 広大な草原に数千本の草を配置したい
  • 森に大量の木を配置したい
  • 岩や石が散乱しているシーンを作りたい
  • 群衆シーン(多数のキャラクター)のバックグラウンド表現
  • パーティクル効果の代替として大量のオブジェクトを配置したい

使わない場面:

  • 個別にアニメーション・移動・回転させる必要があるオブジェクト
  • プレイヤーキャラクターなどの個別の制御が必要
MultiMeshInstance3DとMeshInstance3Dの比較
図1: MultiMeshInstance3Dなら1つのDrawCallで大量のメッシュを描画できます

主なプロパティと機能

プロパティ説明
multimeshMultiMesh描画するメッシュとインスタンス情報を保持するリソース
mesh(MultiMesh内)Mesh描画の基になるメッシュ(Mesh3D、PrismMeshなど)
instance_count(MultiMesh内)intメッシュのインスタンス数
transform_format(MultiMesh内)enum2D / 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)
MultiMeshで配置した草木
図2: MultiMeshInstance3Dで効率的に大量の草を配置したシーン

もっと使いこなす:カスタマイズできるパラメータ

まずは基本を動かしてみてから、余裕が出たら試してみてください。

パラメータ説明調整のポイント
instance_countインスタンスの総数多いほど詳細だがVRAM使用量増加。GPUメモリに注意
transform_formatTRANSFORM_2D vs TRANSFORM_3D2D値のみなら2D形式でメモリ節約
use_colors色情報の有効化ONでメモリ増加。色が不要なら OFF
mesh描画メッシュ複雑なメッシュはGPU負荷増加。シンプルなメッシュを推奨
visibility_aabbカリング用のAABB画面外のインスタンスをスキップする範囲を設定
MultiMeshのパフォーマンス最適化
図3: インスタンス数とフレームレートの関係

まとめ

MultiMeshInstance3Dは、GPUインスタンシングの力を活用して、同一メッシュを数千個規模で効率的に描画できる強力なノードです。

  • 1つのDrawCallで複数インスタンスを描画でき、パフォーマンスが大幅に向上
  • Set_instance_transform()でインスタンスの位置・回転・スケールを個別設定可能
  • grass/trees/rocksなど、静的オブジェクトの大量配置に最適

次回は、3D表面にテクスチャを投影して貼り付けるDecalノードを解説します。弾痕や血痕、落書きなど、ダイナミックな視覚効果を実現する手法を学んでいきましょう。

関連性の高いノード解説記事

この記事はGodot 4.xをもとに執筆しています。

コメント