【Godot】ルール画像を使ったトランジション演出

# 概要
今回の記事はこちらの記事……

* [【Godot】トランジション(画面切り替え)をシェーダで作る](https://ueshita.hatenablog.jp/entry/2020/09/17/210321)

を参考に、トランジションの実装方法をまとめました。
（ほぼ同じシェーダーになりますが……）

![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/a83de67f-6457-dbcb-b726-e83c138aa3e6.gif)

# トランジションの実装

## 素材画像
いつもの背景画像を使います。名前は "bg.png" で保存。
![bg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/dc1171e5-ba9e-3e83-83c1-060ae1b0924b.png)

## 画像を登録
プロジェクトに画像を登録して、ドラッグ＆ドロップで配置します。
![Godot_Engine_-_TestTransition_-_Main_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/336d4d67-c014-0b4c-b9ac-6359e06b2d60.png)

## シェーダーの作成

作成した bgノード(`Sprite`)のインスペクタから、`CanvasItem > Material > Material > [空]`をクリックして、「新規 ShaderMaterial」を選択します。
![Banners_and_Alerts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/e21cd8b7-107a-d9a6-67ec-328ffe2c637e.png)

作成した ShaderMaterialをクリックして、`Shader > [空]` をクリックして「新規 Shader」を選びます。
![Banners_and_Alerts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/aa62997a-51e2-e024-2574-31091b7b5e91.png)

シェーダーコードは以下のように記述します。

```glsl
shader_type canvas_item;

uniform float SoftRange = 0.2;              // 境目を半透明にする幅
uniform float Value : hint_range(0.0, 1.0); // フェード値
uniform sampler2D Mask;                     // ルール画像

void fragment()
{
	// 基準値を計算
	float rangedValue = Value * (SoftRange * 2.0 + 1.0) - SoftRange;
	// 最小値と最大値を決める
	float minValue = rangedValue - SoftRange;
	float maxValue = rangedValue + SoftRange;
	// ルール画像の濃度を取得
	float maskValue = texture(Mask, UV).r;
	// smoothstep(エルミート補完)で透過値を決定
	float alpha = smoothstep(minValue, maxValue, maskValue);

	// この実装だと黒フェード.
	//COLOR = vec4(vec3(0.0), alpha);
	// 割り当てたテクスチャを使うように修正
	vec4 color = texture(TEXTURE, UV);
	COLOR = vec4(color.rgb, alpha);
}
```

もとのコードでは黒フェードする前提だったので、Textureに割り当てた画像そのものを透過するようにしてみました。

## スクリプトの作成
このシェーダーを呼び出すスクリプトを作成します。bgノードにスクリプトをアタッチして以下のように記述します。

```gd:bg.gd
tool
extends Sprite

# 項目を半透明にする幅
export(float) var soft_range = 0.02
# フェード値
export(float, 0.0, 1.0) var fade_value = 0.0
# ルール画像
export(Texture) var mask_img

func _process(delta: float) -> void:
	# シェーダーパラメータを設定
	material.set_shader_param("SoftRange", soft_range)
	material.set_shader_param("Value", fade_value)
	material.set_shader_param("Mask", mask_img)
```

tool宣言は、シーンの再読み込みが必要なので、シーンを保存して開き直します。
すると、bgノードのインスペクタに `Script Variables`が追加されています。

![Godot_Engine_-_TestTransition_-_Main_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/833cb182-7c3a-b1d7-7784-20d752374e88.png)

## ルール画像の登録
For You様のサイトから好きなルール画像をダウンロードします。

* [For You](https://4you.bz)

今回は、https://4you.bz/rule1080p こちらのページにある以下の画像を使いました。
![ルール画像フルHD版___For_You.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/7f0acd39-36b9-a762-71ad-1416991ae954.png)
（リンクウェアなので縮小しています）

こちらのサイトからありがたくダウンロードさせていただき、"mask.png" にリネームしてプロジェクトに登録します。
そして、 bgノードのインスペクタの `Script Variables > Mask Img > [空]` をクリックして、「読み込み」を選びます。
![Godot_Engine_-_TestTransition_-_Main_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/494d4d8f-fe28-5451-1bbb-19e0c7d269bf.png)
そして、"mask.png" を選択して、「開く」をクリックします。
![Godot_Engine_-_TestTransition_-_Main_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/76312673-4b0f-daaa-e880-590f8a31ada8.png)

`Mask Img`にルール画像が設定されました。
![Godot_Engine_-_TestTransition_-_Main_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/c0e77dab-1390-5008-b9ce-c814a079b64e.png)

`Soft Range` を 「0.02」あたりに変更して、`Fade Value`の値を動かすとトランジション演出ができます。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/a83de67f-6457-dbcb-b726-e83c138aa3e6.gif)

参考にした記事にも書いてあることですが、キャプチャした画像に対して、このトランジションを適用するとクロスフェードで画面遷移を行えたり夢が広がりますねー。

Viewportを使ったキャプチャの方法は、以下のページにまとめています。

* [【Godot】Viewportから画面をキャプチャする方法](https://qiita.com/2dgames_jp/items/8723824d410634fcfc74)

# 参考

* [【Godot】トランジション(画面切り替え)をシェーダで作る](https://ueshita.hatenablog.jp/entry/2020/09/17/210321)