【Godot】VisualShaderの基本的な使い方

# 概要
この記事では、ノードをつないでシェーダーを作成する視覚的にわかりやすい「VisualShader」に基本的な使い方について紹介します。

# シェーダー確認用のプロジェクトの作成
まずはプロジェクトを作成し、2Dシーン(`Node2D`)を追加して、"icon.png" を`Sprite`として登録します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/a59a0c93-5905-e827-e82b-8653db64e0d5.png)

## VisualShaderエディタの起動
作成した iconノードのインスペクタから `CanvasItem > Material > Material > [空]` をクリックして、「新規 MaterialShader」を選びます。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/7dad3ea8-aed4-6bcb-2165-67dd1d1ea724.png)

作成した MaterialShaderをクリックして、`Shader > [空]`をクリックして、「新規 VisualShader」を選びます。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/b50f6310-0863-8214-56cc-7209087a989a.png)

作成した VisualShaderをクリックすると、「VisualShaderエディタ」が表示されます。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/24af655b-4ffa-79ef-7e18-b0a658b5be4f.png)

## VisualShaderエディタの設定
VisualShaderエディタを起動した直後は、`Shader > Mode`が「Spatial」(3D空間で有効)になっているので「CanvasItem」(2Dで有効)に変更しておきます。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/68ff093d-13be-843c-092f-e2409809b12c.png)

## 点滅するアニメーションを作る
まずは画像が点滅するアニメーションを作ってみます。
エディタ上の何もないところで右クリックするか、左上の「ノードを追加」をクリックします。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/7ca1e97e-c910-b79f-1af7-fd098f567309.png)
シェーダーノードの作成ダイアログが表示されるので、以下の操作を行います。

1. 検索ボックスに「time」と入力します
2. 「Time」ノードをダブルクリックで選択します

![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/17d51b7f-da2b-5ea2-44b6-a904f0dbbb26.png)
すると、`Input > Time`ノードが追加されます。

![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/7c6e166b-65e9-e893-5fd7-bddf2779b3d5.png)

簡単にこれらのノードについて説明すると、「Input」は入力パラメータです。そして「Time」ノードは時間経過によって増加するパラメータなので、テスト用の値として動作を確認するパラメータとして最適です。
そして「Output」が最終的な出力値です。例えば`Output > Color` に赤色を設定すると最終的な画像は「赤色」になります。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/3ce98b22-e3fb-00c2-6b94-13c17c172283.png)

点滅アニメーションの続きに戻ると、`Input > Time`ノードの右側にある「青い丸」を右側にドラッグして離します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/c82c9d22-2596-8eb6-2c73-32d75ed52b15.png)
すると、シェーダーノード作成ダイアログが表示されるので、検索ボックスに「sin」と入力して、`Scalar > Functions > Sin`を選択します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/65948d21-4377-0c00-b62c-6b511f59a3ea.png)
すると、`ScalarFunc > Sin` ノードが作成されます。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/8ec97da7-a9b6-3088-9445-05469db90593.png)
ここで、Sinのとなりにある「閉じている目アイコン」をクリックします。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/0ee4d7e0-4d2b-6c5a-875c-d86bdb92c350.png)
すると以下のように点滅状態が確認できます。これは `Input > time`が時間経過で値が増加して、それをSinカーブで変化させることで、「-1.0〜1.0」の値となっているためです。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/4e4c6cd0-c1fd-0031-7d5e-edbe2a80f34b.gif)
このように、VisualShaderを使うメリットは、計算途中の状態が見た目でわかることです。

Sinの動きが確認できたところで、Sinノードを `Output > Alpha` に接続します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/db817670-7ef8-a3b6-f5cd-e68628cd9a8d.png)

すると画像が点滅するようになったのですが、単色になってしまっています。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/e9c8789c-5873-4973-0af5-07472fcf59f6.gif)
これは色情報が設定されていないためです。

ノードエディタの何もないところで右クリックしてシェーダーノード作成ダイアログを表示します。
そして、"texture"で検索して、`Textures > Functions > Texture` を選択します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/dc7b2c7b-8c48-b68f-00d5-fa527cd9e731.png)

`Texture`のドロップダウンから「Texture2D」を選びます。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/0df88d7c-1ce1-4539-bcf2-79db3344fd4e.png)

最後に、`Texture > rgb` から `Output > Color` に接続します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/0a960ddf-c5e8-9521-79b3-d6cee29c0b2c.png)

これで点滅処理は実装できたのですが、色味が変わっていますね……。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/061d1a71-4a16-0d20-55a8-8abcb653d8c8.gif)

これは Alpha の値がマイナスになっているためです（`sin()` の戻り値は -1.0〜1.0）

Alphaを 0.0〜1.0になるように修正します。
`Scalar > Functions > Abs`ノードを追加します。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/f49633c4-5e46-61ab-7697-c0fdc476a1ff.png)

`Sin`ノードから `Abs`ノードに接続し、 `Abs`ノードから`Output > Color` に接続するようにします。
![Godot_Engine_-_TestVisualShader____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/2d4df158-dfb4-a1bf-209a-4cd7c98bf504.png)

すると、正しく点滅処理を行うようになります。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/94d90425-a858-2b30-3813-36398de378f9.gif)

# 参考

* [Godot Docs » シェーディング » ビジュアルシェーダー](https://docs.godotengine.org/ja/stable/tutorials/shading/visual_shaders.html)