はじめに
Unity 2020.2 HDRP のサンプルプロジェクトを見ると、
きれいなお部屋の中を歩き回ることができます。
このお部屋、竹の根元に蝶々がいます。かわいい。
この蝶々はVFX Graph で作られています。
今回は この VFX Graphを読んでいきたいと思います。
Inspector上の設定
Visual Effect コンポーネントを見ると、以下のような設定になっています。
Rendering Layer Mask
Rendering Layer Maskの部分が Mixed... になっているのが気になります。
Rendering Layer Maskを変えてみる
蝶々を拡大すると、以下のような表示になっています。
Rendering Layer Mask を Decal Layer default のみ有効にすると、白っぽい感じになります。
Light LayerDefault を有効にすることで、VFXの描画結果がライトの影響を受けるようになるみたいです。
Light LayerDefaultのみをONにすると以下のような表示になります。
Properties
続いては、Propertiesを見てみます。
パラメータは以下のようなものを表しているようです。
プロパティ | 意味 |
Count | 蝶々の生成数 |
Radius | 蝶々を生成する位置の半径 |
Wing Animation Speed | 蝶々の羽ばたくアニメーションの速さ |
VFX Graphのプロパティからアニメーションを制御できるのが興味深いと思いました。
VFX Graphの中を見てみる
次は、VFX GraphアセットButterFliesの中を覗いていきます。
コンテキスト
ButterFlies アセットの中身は以下のようになっています。
コンテキスト | やっている内容 |
Spawn | 蝶の生成 |
Initialize | 蝶の初期化 |
Update | 蝶を動かす |
Output | 蝶を画面に出す |
Spawn
Spawn コンテキストでは、 Single Burst ブロックが使用されています。
VFX開始時に、一度だけ Count 分の蝶を生成しています。
Initialize Particle
その次のInitialize Particle コンテキストは以下のようになっています。
Initialize Particle コンテキストには、以下のようなブロックが接続されています。
ブロック | やっている内容 |
Add Position (Shape: Sphere) | 蝶の初期位置を、球内部のランダムな位置に設定する |
Set Direction | 蝶の向きを設定 |
Set Tex Index | 蝶のテクスチャ番号設定 |
Add Velocity from Direction & Speed (Random Direction) | 速度を足す |
Add Position
蝶の初期位置を、球内部のランダムな位置に設定しています。
Set Direction
SetDirectionブロックでは、位置と外積を利用して、球に沿って下方向へ向かうような向きを設定しています。
やっていることがやや複雑なので紐解いていきます。
Get Attribute : position current
Get Attribute は パーティクルが持つ情報(Attribute)を取得するノードです。
今回は position currrent(現在の座標)を取得しています。
今回、蝶(パーティクル)は球の内部にまばらに存在しています。
Houdiniを使って可視化してみると、以下のようになるでしょうか。
Normalize (Vector3)
Normalizeはベクトル長を1にする(正規化)を行うノードです。
座標にNormalizeをかけると、点は半径1の球の表面に並びます。
Cross Product (Vector 3)
Cross Product は ベクトルの外積を行うノードです。
外積結果を黄色い線として、表示してみると以下のようになります。
時計周りの向きになります。
さらにこのベクトルを、元の座標と外積しています。
ベクトルの計算結果は以下のようになります。
球に沿って下方向に向かうベクトルになりました。
ノードだけを見るとなかなかイメージがつかみにくいですが、可視化すると分かりやすいですね。
このベクトルは、Set Direction ブロックへ入力されます。
つまり、蝶は最初は下を向いているということになります。
実際のノードと、ベクトルの可視化を並べてみました。
Set Tex Index
この蝶々の元素材は以下のようなテクスチャシートになっています。
Set Tex Indexブロックでは、テクスチャシートの左から何番目のテクスチャを使うか、という番号を設定した物になります。
Add Velocity from Direction & Speed (Random Direction)
このブロックは、パーティクルのDirectionの方向に対して、ランダムな速度を加算しています。
先ほど、Set Direction ブロックにて以下のようなベクトルを設定していたので、
球に沿って下方向に対して、長さ0.2 ~ 1.0 のランダムな速度が足されることになります。
以上で Initialize Particle コンテキストは終わりとなります。
次に Update Particle コンテキストを見ていきます。
Update Particle コンテキスト
Updateコンテキストでは、以下のようなブロックが接続されています。
ブロック | やっている内容 |
Force | 力を足す |
Turbulence | 速度に乱流を与える |
Set Velocity | 速度が0.5を下回らないように制限を加える |
Set Scale.XY | パーティクルの大きさの設定 |
Set Pivot.X |
メッシュのピボットを設定 (メッシュの回転の中心位置を決める) |
Force
Forceブロックでは、蝶にかかる外力を設定しています。
PositionとDirectionの外積
ノードだけ見てもよくわからないので、Houdiniを使って可視化してみます。
Direction
Initialize コンテキストにて設定したDirectionですが、
時間が経過するとパーティクルは移動し、以下のようにバラバラな向きになります。
どのパーティクルも、下方向になっています。
PositionとDirectionの外積をとると、球に沿ったベクトルになります。
つまり、原点(0,0,0)の周りをグルグル回るようなベクトルになります。
横方向ベクトルへランダム値を乗算
ここで求めた横方向ベクトルに、パーティクルごとのランダムな数値を乗算し、
速度に揺らぎを持たせています。
中心へ向かう引力
先ほどにベクトルに対して、座標(position) の符号を反転したものを加算しています。
これは原点へ向かって引き寄せる力になります。
座標は正規化せずに符号反転したものを使っているので、
パーティクルが原点から離れるほど強い引力になり、
パーティクルが原点に近づくと弱い引力になります。
最終的には以下のようなベクトルが外力となります。
横方向ベクトルを灰色、 中心へ向かうベクトルを黄色で表しています。
Turbulence
Turbulenceブロックではパーティクルに乱流を与えるもので、
蝶の動きに揺らぎを与えます。
Set Velocity
Set Velocityはパーティクルの速度を上書きするものです、
パーティクルの速さ(VelocityのLength)が0.5を下回らないように制限を与えています。
Set Scale / Set Pivot
ここでは、パーティクルのスケールやピボットを設定しています。
0.45や0.6という謎の数字が登場しますが、アートの都合によってこのような数値になったのだと思います。
Set Pivotを外してみた
通常の蝶はこのような表示になっていますが、
Set Pivot を無効にすると、以下のようないびつな表示になってしまいます。
以上でUpdate Particleは終わりとなります。
次にOutput 系のコンテキストを見ていきます。
Output コンテキスト
Orient Adnvanced (羽の向きの設定)
パーティクルの向きの設定は Orient Adnvanced ブロックで行っています。
Axis Z、Axis Y の挙動について
Axis Z や Axis Y を設定した際のメッシュの向きは以下のようになります。
メッシュの面はAxisZを向き、メッシュの上方向はAxisYに一致するようにメッシュ自体が回転します
ちなみに、パーティクルのローカルのX軸(赤い線)は, Axis Z と Axis Y外積に一致しています。
蝶の羽の向き
今回の蝶パーティクルのAxis は以下のように設定されています。
- Axis Z : 進行方向に対して横向き
- Axis Y : 上方向
蝶のはばたき
蝶の羽ばたきは、Add Potision や Set Angle.Y によって実装されています。
Y方向の位置変化(Add Position) + 羽の回転(Set Angle.Y) をSine波で動かすことで羽ばたきを表現しています。
Sine波が大きくなると、羽が大きく広がり、蝶も早く移動するような実装になっています。
Angle.Y = 0 だと、羽が完全に閉じた状態になります。
Set Angle.X
最後のSet Angle.X は、羽のX回転を設定しています。
以下のような軸で回転します。
関連
Unity 2020.2 TECH ストリームがダウンロード可能になりました
Unity 2020.2 TECH Stream is now available for download (unity3d.com)