【Godot】Godot 2Dライティング入門: PointLight2Dと影の設定で実現する深みのある表現

作成: 2025-12-10

PointLight2DとLightOccluder2Dで2Dライティングと影を実装。基本設定からよくある問題の解決法まで。

概要

Godot Engineで制作する2Dゲームにおいて、ライティングは単なる装飾以上の役割を果たします。適切に設定された光と影は、シーンに深み雰囲気を与え、プレイヤーの注意を誘導し、ゲームの世界観を劇的に向上させます。

この記事では、Godotの2Dライティングシステムの核となるPointLight2Dノードと、それを使った 影(シャドウ) の設定方法に焦点を当て、初心者から中級者の方がつまずきやすいポイントを解消しながら、実践的なベストプラクティスを解説します。

この記事を読むことで、あなたは以下のことを習得できます。

  • Godot 2Dライティングの基本構造と仕組み
  • PointLight2Dノードの基本的な使い方と主要プロパティ
  • LightOccluder2Dノードを使った動的な影の生成方法
  • ライティング設定で陥りがちな間違いとその解決策

基本概念の解説

Godotの2Dライティングシステムは、主に以下の3つの要素で構成されています。

要素ノード役割
光源PointLight2D / DirectionalLight2D光を放ち、シーンを照らす。PointLight2Dは点光源、DirectionalLight2Dは太陽光のような平行光源として機能します。
光を遮るオブジェクトLightOccluder2D光を遮断し、影を生成するための境界を定義します。
照らされるオブジェクトCanvasItemを継承するノード (Sprite2D, TileMapなど)光源の影響を受け、影を落とす、または影に隠れる対象となります。

PointLight2Dの仕組み

PointLight2Dは、特定の点から全方向に光を放射するノードです。その光の形状は、Textureプロパティに設定するテクスチャによって定義されます。一般的に、中央が明るく外側に向かって暗くなるグラデーションテクスチャを使用します。

ヒント: 外部ツールで画像を用意しなくても大丈夫です。Textureプロパティのプルダウンから New GradientTexture2D を選択し、FillRadial(放射状) にすることで、きれいな光のグラデーションをエディタ内で作成できます。

主要なプロパティ:

  • Texture: 光の形状を定義するテクスチャ。
  • Color: 光の色。
  • Energy: 光の強度。
  • Mode: 光とシーンのブレンド方法(Add, Sub, Mix, Mask)。デフォルトのAddが最も一般的です。

影の生成: LightOccluder2D

影を生成するためには、光源(PointLight2D)と、光を遮るためのLightOccluder2Dノードが必要です。

  1. PointLight2D側の設定: Shadow > Enabledオンにします。
  2. LightOccluder2D側の設定: 影を落としたいオブジェクト(壁や障害物など)にLightOccluder2Dノードを追加し、OccluderプロパティにOccluderPolygon2Dリソースを設定します。このポリゴンが光を遮る境界となります。

よくあるつまずきポイント

初心者が2Dライティングでつまずきやすい、代表的な間違いと誤解を解説します。

影が全く表示されない

PointLight2DShadow > Enabledをオンにしたのに影が出ない場合、最も多い原因はLightOccluder2Dノードの不足です。

  • 間違い: PointLight2Dを配置し、Shadowを有効にしただけで、影が自動的に生成されると思い込んでいる。
  • 真実: Godotの2Dライティングシステムでは、光を遮るための境界LightOccluder2Dノードで明示的に定義する必要があります。衝突判定(CollisionShape2D)とは別物です。

シーン全体が真っ暗になってしまう

PointLight2Dを配置した途端、シーン全体が暗くなる、または光が当たっている部分以外が真っ暗になる現象は、CanvasModulateノードWorldEnvironmentノード の設定が原因であることがあります。

  • 解決策:
    1. CanvasModulate: シーンのルートノードにCanvasModulateノードがある場合、そのColor黒(#000000) になっていないか確認してください。これが黒だと、シーン全体が暗くなります。
    2. LightOccluder2Dの配置ミス: 意図しないオブジェクトにLightOccluder2Dが設定され、シーン全体を覆うように光を遮断している可能性があります。

補足: WorldEnvironmentノードは主に3Dシーン用です。2D/3Dを混在させている場合は環境光の設定が影響することもありますが、純粋な2Dゲームであれば、まずはCanvasModulateの色と、各スプライトのModulateプロパティを優先して確認してください。

光源のテクスチャが不自然に見える

デフォルトのPointLight2Dのテクスチャは、光の減衰が急激で不自然に見えることがあります。

  • 解決策: PointLight2DTextureプロパティに、より滑らかに減衰するカスタムのグラデーションテクスチャを設定します。また、Texture Scaleプロパティを調整して、光の範囲を広げたり狭めたりすることで、自然な見た目に近づけることができます。

影の形がおかしい・逆に出る

LightOccluder2Dを設定したのに影が奇妙な方向に出たり、オブジェクトの内側が影になってしまうことがあります。

  • 解決策: OccluderPolygon2Dを描く際の 頂点の順番(時計回り/反時計回り) が影響している可能性があります。インスペクタの Cull Mode を変更してみるか、ポリゴンの頂点を描く方向を変えてみてください。

ベストプラクティスと実践例

ここでは、よりプロフェッショナルな2Dライティングを実現するための実践的なテクニックを紹介します。

LightOccluder2Dの効率的な設定

タイルマップ(TileMap)を使用している場合、すべてのタイルに個別にLightOccluder2Dを設定するのは非効率的です。

推奨される方法:

  1. TileSetでOccluderを設定: TileSetリソース内で、光を遮断したいタイル(壁など)に対してOcclusion Layerを設定します。これにより、TileMapノード全体が単一のLightOccluder2Dとして機能し、パフォーマンスが向上します。
  2. OccluderPolygon2Dの最適化: OccluderPolygon2Dを作成する際、頂点(Vertex)の数を必要最小限に抑えます。複雑すぎるポリゴンは描画コストが増加し、パフォーマンスに影響を与えます。

GDScriptによる動的な光源制御

プレイヤーの動きやゲームイベントに応じて光源を動的に制御することで、ゲームプレイに緊張感やリアリティを加えることができます。

例えば、プレイヤーが懐中電灯を持っている場合、その光源をプレイヤーに追従させ、エネルギーが時間とともに減少する処理を実装します。

# Player.gd (PointLight2Dノードを子として持つことを想定)

extends CharacterBody2D

@export var max_light_energy: float = 1.5
@export var energy_drain_rate: float = 0.05 # 1秒あたりの減衰量

@onready var flashlight: PointLight2D = $PointLight2D

func _process(delta: float) -> void:
    # プレイヤーの向きに合わせて光源を回転させる(オプション)
    # var mouse_pos = get_global_mouse_position()
    # flashlight.rotation = (mouse_pos - global_position).angle()

    # エネルギーを徐々に減少させる
    if flashlight.energy > 0.0:
        flashlight.energy -= energy_drain_rate * delta
        flashlight.energy = max(0.0, flashlight.energy)

    # 懐中電灯のオン/オフ切り替え
    if Input.is_action_just_pressed("toggle_light"):
        flashlight.enabled = not flashlight.enabled

    # エネルギーがゼロになったら自動でオフにする
    if flashlight.energy == 0.0:
        flashlight.enabled = false

# アイテムなどでエネルギーを回復する関数
func restore_energy(amount: float) -> void:
    flashlight.energy += amount
    flashlight.energy = min(max_light_energy, flashlight.energy)
    if not flashlight.enabled:
        flashlight.enabled = true

注意: 上記の例ではtoggle_lightという入力アクションを使用しています。「プロジェクト設定」→「入力マップ」からtoggle_lightを追加し、キーボードやゲームパッドのボタンを割り当てておいてください。

Light Occlusionのマスクレイヤー活用

Godot 4では、Light2DノードのItem Cull Maskと、CanvasItemノードのLight Maskプロパティを組み合わせることで、どの光源がどのオブジェクトを照らすかを細かく制御できます。

例えば、「通常光」と「特殊な魔法の光」を分けたい場合、以下のように設定します。

  1. 通常光 (PointLight2D): Range > Item Cull Maskをレイヤー1に設定。
  2. 魔法の光 (PointLight2D): Range > Item Cull Maskをレイヤー2に設定。
  3. 通常のオブジェクト (Sprite2Dなど): Visibility > Light Maskのレイヤー1をオンにする。
  4. 魔法の光にのみ反応するオブジェクト: Visibility > Light Maskのレイヤー2をオンにする。

これにより、複雑なシーンでもライティングの適用範囲を論理的に分離し、パフォーマンスの最適化にも繋がります。

注意: Godot 4ではプロパティ名が変更されています。光源側はRange > Item Cull Mask、照らされる側はVisibility > Light Maskとなっています。

まとめ

Godotの2Dライティングは、PointLight2DLightOccluder2Dの組み合わせを理解することが成功の鍵です。

  • PointLight2D: 光源そのもの。テクスチャとエネルギーで光の見た目を調整します。
  • LightOccluder2D: 影を落とすための境界。影を生成するには必須のノードです。

これらの基本をマスターすれば、あなたの2Dゲームは、単調な平面表現から、光と影が織りなす深みのある世界へと進化するでしょう。次に学ぶべきステップとしては、**法線マップ(Normal Map)**を使ったよりリアルなライティング表現や、カスタムシェーダーによる光の表現の拡張に挑戦することをお勧めします。