Unityブログ記事の木を自然に揺らすシェーダーグラフを見てみます。GitHubからサンプルプロジェクトをダウンロードできます。
頂点カラー
頂点カラーを使うとシェーダーグラフで頂点ごとに違う値を使えます。
シェーダーグラフ
シェーダーグラフは2つの部分から始まります。左上が幹の揺れ、左下が揺れ具合で、それをかけあわせて頂点位置に足します。
幹の揺れ
メッシュを揺らすには三角関数を使います。「Time」と「Sine」ノードで正弦波を作れます。
Sineの入力値に値をかけると周期、足すと位相が変わります。出力値にかけると振幅が変わります。
この値とLerpノードを使って複雑な波を作れます。
入力のBとTは同じ -0.1~0.1の値になります。大きい波と小さい小刻みな波を交互に繰り返します。
Directionプロパティとかけて方向を変えられるようにします。
幹の揺れ具合
左下の部分では、まず幹の剛性を1から引いた値を調整して、オブジェクト空間の高さとかけています。それを「Strength」プロパティとかけます。
これで木の高さに沿ったグラデーションになります。
これに1を足した値の4乗から2乗を引くと、シンプルなグラデーションでなく上の方がより高い値になりました。
頂点を移動
この上の部分と下の部分をMultiplyノードでかけあわせます。上の部分が基本の揺れで、下の部分が高さに応じた揺れ具合です。
できた揺れを、Positionノードの出力と足すことで頂点を移動させます。揺れ(Vector2)のxをオブジェクト空間の位置のxに、揺れのyを位置のzに足しています。これで頂点は真横に移動します。
これをNormalizeノードで正規化して長さを1にした後、元の位置ベクトルの長さをかけます。
これで横方向の移動が弧を描くように変換されます。
この値が葉と枝の揺れと掛け合わさって、マスタースタックのPositionに接続されます。
葉と枝の揺れ
葉と枝の揺れは中央にある残りのノードで作られます。
この部分は、細かい揺れを作る部分と、各方向への揺れ具合を設定する部分に分けられると思います。
この2つが掛け合わされた後、幹の揺れに足されます。
葉と枝の揺れ具合
葉と枝の揺れ具合は、頂点カラーと柔性とTurbulenceプロパティが掛け合わされています。
葉の値がxとz、枝の値がyになるVector3の値が作られます。葉の値にはそれぞれオブジェクト位置のxとzが掛け合わされています。
葉と枝の揺れ
下の部分は複雑な位相を作る部分と、正弦波に似た波を作る部分にわけられると思います。
前半は、まずオブジェクト位置と定数の内積を計算しています。これである方向に沿ったグラデーションができるようです。
それに頂点カラーの緑を足しています。
枝ごとに濃淡が変わります。
さらに、はじめの幹の揺れの値との内積を計算しています。
これは揺れが加わったグラデーションになります。
頂点位置と頂点カラーの緑、幹の揺れに基づいた値がTimeノードに足されます。これで位相が複雑に変わります。
さらにこれを4Dベクトルにして、それぞれに別々の振動数をかけています。
このベクトルを入力として、「Fraction」「Triangle Wave Sample」「Smooth Curve Sample」ノードを使って、低コストに正弦波に近い波を作っています。
参考:https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-16-vegetation-procedural-animation-and-shading-crysis4Dベクトルのxとy、zとwを足して2Dベクトルにし、Swizzleノードで(x, y, x)というベクトルにしています。
これで葉と枝の値とかけられて、幹の揺れに足されます。
これがマスタースタックのPositionに接続されます。
まとめ
このように、幹と枝葉に分けて、揺れと揺れ具合をかけ、頂点位置に足していくことで複雑な揺れをつくっていると思います。