【Godot】2D画像をもとに擬似的な影を実装する方法

この記事では、2D画像をもとに擬似的な影を実装する方法について紹介します。

影の実装

画像の登録

今回の素材は「立ち絵素材 わたおきば」様よりお借りしています。

背景が明るいほうがわかりやすいので、ColorRect を背面に配置して明るい灰色にします。

登録したキャラクター画像は Chara にノード名を変更しておきます。

影用のSpriteの作成

影用のSpriteとして、Chara を複製し、名前を Shadow にリネームします。

図ではわかりやすいように位置をずらしていますが、Shadowノード の Transform > Position は 0 (初期値) にしておきます。

そして、Charaノードを選択して、インスペクタから Z Index > Z Index を 「1」にしておきます。

これはキャラクターを影よりも前面に表示したいためとなります。
さらに Shadow ノードを選択して、インスペクタから Z Index > Z Index を 「-1」にしておきます。

少しややこしいですが、Z Indexの並びは以下のようになります。

Mainシーン
 +-- ColorRect (0) => 一番奥
 +-- Chara (1) => 一番手前
      +-- Shadow (1-1=0) => 真ん中

シェーダーの追加

Shadowノードを選択した状態で、CanvasItem > Material > Material > [空] をクリックして「新規 Shader Material」を追加します。

作成されたMaterialをクリックして、Shader > [空] をクリックし、「新規 Shader」を選びます。

するとシェーダーエディタが表示されるので以下のコードを記述します。

shader_type canvas_item;

uniform float shearAngleX = -45.0;
uniform float sunAngle = 45.0;

//const float SHEAR_ORIGIN_Y = 1.0; // 左上が原点
const float SHEAR_ORIGIN_Y = 0.5; // 中心が原点

// 頂点シェーダー
void vertex()
{
    vec2 v = VERTEX;

    float originOffsetY = SHEAR_ORIGIN_Y / TEXTURE_PIXEL_SIZE.y;
    v.y -= originOffsetY; // 原点をずらす
    // 影の傾きを計算
    v.y *= cos(radians(shearAngleX)) / tan(radians(sunAngle));
    v.x += tan(radians(shearAngleX))  * v.y;

    v.y += originOffsetY; // 原点をもとに戻す

    VERTEX = v;
}

// フラグメントシェーダー
void fragment()
{
    // 薄い黒色にする
    vec4 color = texture(TEXTURE, UV);
    color.rgb = vec3(0, 0, 0);
    color.a *= 0.5;
    COLOR = color;
}

シェーダーコードを記述すると、以下のように影が描画されます。

スクリプトの追加

Shadowノードにスクリプトをアタッチして以下のように記述します。

tool
extends Sprite

export(float, -90, 90) var shear_angle_x = -45 
export(float, 45, 90) var sun_angle = 45

func _process(delta: float) -> void:
    material.set_shader_param("shearAngleX", shear_angle_x)
    material.set_shader_param("sunAngle", sun_angle)

tool宣言をしているので、シーンをいったん保存して開き直します。

するとエディタから影の調整ができるようになります。

参考