はじめに
3Dゲームをプレイしていて「銃で撃った壁に弾痕が付く」「キャラが血を流している」「地面に足跡がある」といった表現を見かけることがあります。こうした動的なテクスチャの貼り付けは、ゲームの世界をより生き生きとさせる重要な要素です。
このような視覚効果を実現するのがDecalノードです。このノードを使うことで、3D表面にテクスチャを投影して貼り付け、ゲームプレイ中に動的に効果を追加できます。
Decalとは?
Decalは、3D表面にテクスチャを投影して貼り付けるノードです。
たとえ: 照写機(プロジェクター)で壁に画像を投影するのと同じように、Decalはテクスチャを3D空間に投影して、表面に張り付きます。もともとのメッシュのテクスチャは変わらず、デカール(新しい画像)が上に重ねられます。
継承ツリー:
Decal → VisualInstance3D → Node3D → Node
このノードを使うべき場面
- 銃で撃った壁に弾痕を付けたい
- キャラから流れた血痕を地面に付けたい
- 建物の壁に落書きやステッカーを貼りたい
- 地面にマーキングや警告シンボルを表示したい
- ゲームプレイ中に動的にテクスチャを追加・削除したい
使わない場面:
- 静的なテクスチャは最初からメッシュに焼き込む方が効率的
- 動くオブジェクト(キャラなど)に追従させたい場合(デカールは固定)

主なプロパティと機能
| プロパティ | 型 | 説明 |
|---|---|---|
| texture_albedo | Texture2D | 投影する色(ベースカラー)テクスチャ |
| texture_normal | Texture2D | 法線マップ(表面の凹凸情報) |
| texture_orm | Texture2D | Occlusion / Roughness / Metallic の3チャンネル |
| texture_emission | Texture2D | 発光テクスチャ(光を放つ部分) |
| size | Vector3 | 投影ボックスのサイズ(X, Y, Z) |
| emission_energy | float | 発光の強さ |
| albedo_mix | float | 元のテクスチャとの混合度(0.0 = 元のまま、1.0 = デカール色100%) |
| upper_fade / lower_fade | float | 上下方向のフェード(投影ボックスの縁で薄れる効果) |
| cull_mask | int | デカールが適用されるレイヤーを指定 |
基本的な弾痕デカールの例:
extends Node3D
func _ready():
# Decalノードを作成
var decal = Decal.new()
add_child(decal)
# 弾痕テクスチャを設定
var bullet_texture = preload("res://assets/textures/bullet_hole.png")
decal.texture_albedo = bullet_texture
# デカールのサイズと位置を設定
decal.size = Vector3(0.5, 0.5, 0.5)
decal.position = Vector3(5.0, 1.5, -10.0) # 壁上の位置
# 透明度を調整
decal.albedo_mix = 0.8
ゲームプレイ中に動的にデカールを生成する例:
extends Node3D
# プレイヤーが射撃した時に呼ばれる関数
func _on_gun_fired(hit_position: Vector3, hit_normal: Vector3):
# Decalを作成
var decal = Decal.new()
add_child(decal)
# テクスチャを設定
decal.texture_albedo = preload("res://assets/textures/bullet_hole.png")
decal.size = Vector3(0.3, 0.3, 0.3)
# 衝突位置に配置
decal.position = hit_position
# 法線方向を向くように回転
decal.look_at(hit_position + hit_normal, Vector3.UP)
# 3秒後に削除(古い弾痕は消す)
await get_tree().create_timer(3.0).timeout
decal.queue_free()
func _input(event):
if event is InputEventMouseButton and event.pressed:
# 簡略版:固定位置にデカールを作成
var random_pos = Vector3(randf_range(-5, 5), 1.5, randf_range(-5, 5))
_on_gun_fired(random_pos, Vector3(0, 0, 1))

もっと使いこなす:カスタマイズできるパラメータ
まずは基本を動かしてみてから、余裕が出たら試してみてください。
| パラメータ | 説明 | 調整のポイント |
|---|---|---|
| size | 投影ボックスのサイズ | 小さすぎると効果が限定的、大きすぎるとテクスチャが歪む |
| albedo_mix | ブレンド強度(0〜1) | 0=透明、0.5=半透明、1=完全不透明。血痕なら0.6〜0.8推奨 |
| upper_fade / lower_fade | フェード距離 | 0.1〜0.3がナチュラル。大きすぎるとぼやける |
| emission_energy | 発光強度 | 0=発光なし、2.0以上で明るい発光。看板などに有効 |
| normal_blend | 法線マップの強さ | 0=フラット、1=完全に法線が反映。凹凸感の調整 |
| cull_mask | 適用対象レイヤー | 特定のオブジェクトにのみデカールを適用したい場合に設定 |

まとめ
Decalは、3D空間の動的なテクスチャ表現を実現する強力なツールです。ゲーム世界をよりリアルで反応的にします。
- プロジェクター型の投影方式でテクスチャをメッシュに貼り付ける
- albedo / normal / emission など複数のテクスチャをサポート
- ゲームプレイ中に動的に生成・削除できるため、ダイナミックな環境変化を表現可能
次回は、3D空間の特定エリアに霧・煙・ガスを配置するFogVolumeノードを解説します。環境効果を使ったビジュアル表現の手法を学んでいきましょう。
シリーズ: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をもとに執筆しています。


コメント