Unityシェーダーチュートリアル 水流を作ってみる
シェーダー
実践編第2弾「水流を作ってみる」。
以前、某案件で地下浸水を作り、
押し寄せる水流をディスプレイスと屈折を組み合わせて表現したので、
それを解説していきたいと思います。
モデルの準備
こんな感じの場所に、こんな感じで水を流してみます。
屈折
まずは、屈折表現から入れていきます。
詳しくは、以前の記事に描いてありますので、そちらを御覧ください。
今回はこんなテクスチャを用意しました。大小2つの押し寄せる波です。
この後ディスプレイスも加える予定なので、タイリングを合わせる為に、
テクスチャスロットの Scale & Offset ではなく、
別のプロパティ(_WaveTiling)を用意してタイリングさせます。
これだけだとまだ良く分かりませんね。
ディスプレイス
次に、同じ形状のハイトマップを用意してディスプレイスさせましょう。
屈折用のテクスチャと同じ要領でハイトマップを展開します。
ハイトマップは1チャンネルで済むので、ノーマルマップよりもブレンドが楽です。
テッセレーションを使用するので
#pragma target 5.0
となっている事に注意して下さい。
だんだん水流っぽくなってきました。
UVスクロールで流れを付ける
_Time でV方向にスクロールさせ、流れをつくりましょう。
_Time の使い方はこちらの記事にも書いてありますので、併せて御覧ください。
各テクスチャのUVをV方向にスクロールさせます。
+ float2(0, _Time.x * _FlowSpeed.x)
屈折用のノーマルマップと対応するハイトマップの流れが、ずれないように気をつけて下さい。
流れが付くと一気に良い感になります。
頂点カラーマスクによる流れの方向分け
頂点カラーをマスクとして利用し、
場所によって、横方向と縦方向に流れるようにして見ましょう。
まずは、以下のように方向を換えたい箇所に頂点カラーを入れます。
黒い部分は今まで通りで、赤い部分だけ方向を換える想定です。
次に、モデルのUVを見てください。左が1つ目のUVで右が2つめのUVです。
2つ目の方は90度回転しています。
頂点カラーの赤をマスクとして、
今までのUV1を利用した波を、UV2を利用した別方向の波に置き換えます。
少しコードが長くなっていますが、UVを変えただけで全く同じ事を繰り返しています。
2つ目のUV取得部分ですが、uv2_WaveTex2 となっています。分解して説明すると、
まず、最初の uv2 の部分は取得したいUVの番号です。
Unity ではモデルに施された4番目のUVまで取得できます。
そして、後の _WaveTex2 がどのテクスチャスロットで設定するかの指定です。
これについては、以前の記事に説明があるので、併せて御覧ください。
このUV取得に際するテクスチャの指定について、今回は深く考えないでください。
ディスプレイスと一致させるために、別プロパティ(_WaveTiling)でタイリング設定をしますが、
何らかのテクスチャ指定をしないとUVを取得できないのが SurfaceShader の記述形式なので、
とりあえず、uv_WaveTex1、uv2_WaveTex2 としているだけです。
uv2_WaveTex1 とは出来ません。
別のUVを取得する時は違うテクスチャを指定しないとエラーになります。
最後に、UV1で展開したテクスチャと、UV2で展開したテクスチャを、 lerp で合成しています。
おわりに
少し冗長なコードになってしまいましたが、押し寄せる水流が完成しました。
ただ単純に"水面"的なテクスチャをスクロールさせるだけの水流より、
遥かにクオリティが高いですね。