UnityではノードベースのシェーダーエディターとしてShaderGraphがあります。
ノーコードで感覚的にシェーダーを作成することが出来るため、非エンジニアの方でも比較的簡単にシェーダーを作成することができます。
自身はまだほとんどShaderGraphに触れてきてなかったため、今回はShaderGraph入門としてURP用の水のシェーダーを作ってみました!
ということで、今回は水のシェーダーの作り方をShaderGraphで作成する方法についてお話ししていきます。
もっといい作り方知ってるよって方いましたら、コメントなどで教えてくれると嬉しいです!
環境
Unity2022.3.18f1
完成系
水のシェーダー作成手順
ShaderGraphを新規作成
Projectウィンドウで
右クリック>Create>Shader Graph>URP>Unlit Shader Graph
から新規のUnlit Shader Graphを作成して、名前をWaterにします。
Litが光の影響を受けるシェーダー、Unlitが光の影響を受けないシェーダーです。
今回は光の影響は不要なのでUnlitシェーダーで作成します。
作成したファイルをダブルクリックで開くと初期状態はこんな感じです。
色を指定するノードの追加
まずは色を指定するノードを作成します。
右クリック>Create Nodeから「Color」で検索してColorノードを追加します。
色を指定して、ColorのOut出力からFragmentのBase Color入力にカーソルをドラッグアンドドロップして繋げると、Previewの色が指定した色になります。
水の揺らめきを表すVoronoiノードを追加
次はVoronoiノードを追加します。
Voronoiノードはプロシージャルに細胞のような見た目を生成できるノイズノードです。
ただしこのままでは白黒の画像なので、このノードで生成した出力結果を先ほどのColorノードと合わせることで色を付けることが出来ます。
色の加算はAddノードで行うことが出来ます。
AddノードのA入力とB入力にそれぞれColorのOut出力とVoronoiのOut出力を繋げます。
これでVoronoiノードで生成した画像に色を付けることが出来ました。
Unityの世界では色は0~1で処理され、黒は(0,0,0)、白は(1,1,1)となるので、
加算をすると黒は加算された色に、白はそれ以上加算できないので白のままとなります。
Smoothstepノードを追加して水の表現に近づける
Voronoiノードを追加したことで模様は出来ましたが、まだ水っぽくはありません。
全体的に白が多すぎるので、ある程度の色までは全部青になっていてほしいです。
つまり、Voronoiノードの出力の黒部分が増えてほしいということですね。
そういう時にはSmoothstepノードを使用します。
Smoothstepノードを使うと、一定の色以下は0にして、一定の色以上は1に限定することが出来ます。
VoronoiノードとAddノードの間にSmoothstepノードを追加して、VoronoiノードのOut出力からSmoothstepノードのIn入力に繋げます。
Edge1入力とEdge2入力の値を調整すると、けっこう水っぽい見た目になりましたね!
Fresnel Effectノードでフレネル反射を追加する
水を斜め上から見た時、空気中と水中の屈折率の違いの影響で、光が反射します。
こういう現象のことをフレネル反射というのですが、それを再現するノードとしてFresnel Effectノードがあります。
Fresnel EffectノードのPower入力の値を調整して、先ほどまでに作成した一番後ろのAddノードとFresnel Effectノードを更にAddノードで合わせます。
これで斜めから見た際に若干白く光って見えるようになります。
Timeノードを使って動くようにする
次は水が動くように設定をしていきます。
VoronoiノードのAngle Offset入力の値を変更すると、水が揺らめくように動きます。
なので、ここの値が自動で変動することで動きを付けられそうです。
こういう時はTimeノードを使って時間を入力値として入れてあげると楽です。
Timeノードを追加して、Time出力からVoronoiノードのAngle Offset入力に繋げます。
これで時間経過で自動で波が揺らめくようになりました。
Tilling And OffsetでUVスクロールさせる
次は水が移動するようにUVスクロールさせてみます。
UVスクロールさせるにはTilling And Offsetノードが使えます。
Tilling And OffsetノードのOut出力からVoronoiノードのUV入力に繋げて、
Offset入力の値を変えることでこのようにスクロールされます。
これにTimeノードを繋げれば自動で動いてくれそうですね。
SinノードとVector2ノードで一方向に行ったり来たりするようにする
今回は一方向に行ったり来たりしてほしいので、ただTimeノードを繋げるのではなく、SinノードとVector2ノードを上手く掛け合わせてみます。
手順はこちらです。
- TimeノードのTime出力からMultiplyノードに繋げて、もう片方の値を0.3にして時間の変動間隔をゆっくりにする
- Multiplyノードの出力からSineノードに繋げて、値を0~1に制限する
- Vector2ノードを作成し、X入力を0、Y入力を0.5にして移動方向を一方向に固定
- 2と3で作ったSineノードとVector2ノードの出力をMultiplyノードで掛け合わせる
- 4で作成したMultiplyノードの出力をTilling And OffsetノードのOffset入力に繋げる
これで一方向にゆっくりと行ったり来たりするノードが作成できました。
Tillingを設定出来るようにして、色々な大きさに対応出来るようにする
上記でほぼ完成なのですが、このままだと大きさを変えた時、模様の粒度も大きくなってしまい、ちょうどいい見た目になりません。
こういう時はTilling設定をして繰り返し表示出来るようにする必要があります。
大きさに応じて自動で変わるようにしてもいいですが、今回はユーザ入力でTillingの値を設定できるようにしようと思います。
まずはプロパティを設定できるようにしましょう。
ShaderGraphエディタ左上辺りにあるウィンドウから、+ボタン>Vector2でVector2ノードを作成して、名前をTillingに設定します。
右上のGraph Inspectorからノード設定が出来るので、Default値は(1,1)にしておきます。
作成したVector2ノードをTilling And OffsetのTilling入力に繋げます。
これでプロパティからTilling設定が出来るようになりました!
シェーダーの作成はこれで完成です!
マテリアルを作成して確認
それでは先ほど作成したシェーダーを使って新しくマテリアルを作成し、確認してみましょう。
新しくマテリアルを作成して、ShaderをShader Graphs/Waterに設定します。
シーン上にPlaneオブジェクトをおいて、Mesh RendererのMaterialsにWaterMaterialをアタッチすれば見た目が確認できます。
大きさに応じてMaterial設定のところからTilling設定を変更できます。
あとはSkyboxを設定してみたり、陸地っぽいものを置いて諸々調整したら海が出来ます。
お疲れ様でした!
コメント