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で大量のメッシュを描画できます

主なプロパティと機能

プロパティ 説明
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)




MultiMeshで配置した草木
図2: MultiMeshInstance3Dで効率的に大量の草を配置したシーン

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

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

パラメータ 説明 調整のポイント
instance_count インスタンスの総数 多いほど詳細だがVRAM使用量増加。GPUメモリに注意
transform_format TRANSFORM_2D vs TRANSFORM_3D 2D値のみなら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 ノード解説

001〜040:各種ノード

041以降:個別ノード解説

  • 041〜050: 基本的なノード群
  • 051〜060: 物理・キャラクター関連
  • 061〜070: パーティクル・エフェクト
  • 071〜075: ライティング基礎
  • 076: MultiMeshInstance3D(このページ)
  • 077: Decal
  • 078: FogVolume
  • 079: LightmapGI
  • 080: ReflectionProbe

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

コメント