ShaderGraphを使ったリアルな草の作り方② ~風でなびかせる~

風でなびかせたい

↓の動画のように風でなびく感じをShaderGraphを使って表現していこうと思います。
youtu.be

前回は草のメッシュを作りました。 niton.hatenadiary.com

今回の記事は以下の動画を参考にしています www.youtube.com

1. ShaderGraphを使えるようにする

UnityでShaderGraphの機能が使うにはURPというレンダリングパイプラインを使用する必要があります。導入はとても簡単です。

Unityのプロジェクトを作成するときに3D(URP)を選択するだけです! ※既存のプロジェクトにURPを導入する方法はこちらの記事を参考にしてみてください。↓
【Unity】Unity 2021.2で変更されたURP設定方法まとめ|yugaki|note

2. ShaderGraphの基礎

では早速ShaderGraphを使ってみましょう。
Projectウィンドウで右クリックをして、Create->Shader Graph->URP->Lit Shader Graphを選択します。(Litにすると周りの光の影響を受け、Unlitは影響を受けません)

ウィンドウの見方

ShaderGraphを作成すると↓のような画面が出てきます

  • MasterStack…シェーダーへの最終的な出力
    • Vertexは頂点の操作を出力する
    • Fragmentは色やテクスチャなどを出力する
  • Blackboard…プロパティとキーワードのリスト
    • プロパティを追加するとインスペクタで編集できるようになる
    • ReferenceでC#で使うプロパティ名を変更できる
  • GraphInspector…ノードごとのインスペクタ
  • MainPreview…プレビュー

ノード

ウィンドウ内で右クリック -> Create Node、もしくはSpaceキーを押すとノードの種類がたくさん表示されます。ここから必要なノードを選んでShaderを作っていきます。

では試しにAddノードを作ってみましょう。上の検索欄で「Add」と入力すると簡単に見つけることができます。
Addを選択すると↓のようなノードが出てきます。

左側のAとBが入力で、右側のOutが出力です。この入出力の部分に他のノードを結びつけて作っていきます。

ではShaderGraphの基本的な使い方がわかったところで、今回の目的である「風になびく草」を作っていきましょう!

3. 全体像

今回は大きく3つのステップでShaderGraphを作っていきたいと思います。(参考動画より)

Step1. メッシュの頂点にワールド座標基準でUV座標を割り当て、UVスクロールする

Step2. ノイズテクスチャを適用して頂点を左右に揺らす

Step3. これだと草の根本も一緒に動いちゃうのでy軸にグラデーションをかけて根本の変化を0にする

4. 解説

準備

まずは前回作ったメッシュとテクスチャをインポートします。Projectウィンドウで右クリックをしてImport New Assetsを選択し、前回作ったメッシュとテクスチャをインポートします。

  • Sample Texture 2Dノードと、BaseTextureプロパティを作りGraph Inspectorでテクスチャを設定します。
  • ShaderGraphのプレビューもあるんですが、シーンのほうが動きがわかりやすいのでシーンに草を配置して確認できるようにします。
    Mesh FilterとMesh Rendererコンポーネントを追加し、画像のように前回作ったメッシュとShaderGraphを適用させたマテリアルを設定します。
  • このままでは後ろから見たときにテクスチャが表示されないので、ShaderGraphのウィンドウのGraphSettingでRender Faceにチェックを入れます。
    また、透過部分を表示しないように、Alpha Clippingにもチェックを入れます。

Step1. 頂点にUV座標を割り当て、UVスクロールする

このようにノードをつなげます。

この部分はUVスクロールのテンプレ的な感じですね。頂点にワールド座標基準でUV座標を割り当てて、それをスクロールしています。
Tiling And OffsetノードのOffsetにTimeノードを作用させることで時間によってUVがスクロールする動きをします。ここではBlackboardで「WindMovement」というVector2型のプロパティを作って時間と乗算することでスクロールの速度を調整しています。

Step2. ノイズテクスチャを使って頂点を左右に揺らす

3つのノードと2つのプロパティを追加します。先程作ったTiling And OffsetノードのOutからGradient NoiseノードのUVにつなげます。
Gradient Noiseはノイズテクスチャを生成してくれます。Scaleはノイズの大きさで、今回は風の密度?を決定しています。
Substractノードは値の引き算をします。ここで0.5を引いているのはおそらく白黒の割合の調整です。ちなみに値的には黒が0、白が1を表しています(結構大事かも)。
Multiplyノードは乗算をします。このノードによって白黒のメリハリを調整しています(大きい値を乗算するとメリハリが強くなる) 。ここではWindStrengthによって風の強さを決定しています。

ではついでに今の状態での出力までしてみましょう。

4つのノードをこのようにつなげて先ほどのMultiplyノードのOutをAddのAにつなげましょう。また、CombineのRGBA出力からVertexのPositionにつなげてみましょう。

Splitノードは入力ベクトルをR,G,B,Aに分割します。Positionを入力とした場合、RGBはそれぞれxyz軸を表します。ここではx成分だけを取り出して先程作ったゆらぎを加算しています。
CombineノードはRGBAの入力から新しいベクトルを作成します。ここではx成分の計算をした後に元のy,z成分をそのまま入力として受け取り、RGBAに合成しています。

今の状態だと↓のような動きになってしまいます。
youtu.be
根本まで一緒に動いていてちょっと気持ち悪いですね笑

Step3. 根元の方を動かさないようにする

では↓の赤線で囲まれている部分を追加していきましょう。

UVノードとSplitノードを組み合わせるとグラデーションを作ることができます。RGBのうちGを使った場合は縦方向のグラデーションになります。
Lerpノードは2つの入力の線形補完を計算します。ここでは縦方向のグラデーションを入力として、元の頂点座標とゆらぎを計算した頂点座標の間を線形補間しています。こうすることで根本に近いところでは元の頂点座標を採択し、葉っぱの先に近いところではゆらぎを計算した頂点の座標を採択します。

完成!

いっぱい配置してライティングを調整してみました。
youtu.be