rn.log

備忘録など

【Unity2020.2 / VFX Graph】HDRPサンプルの蝶のVFXを読んでみる

はじめに

Unity 2020.2 HDRP のサンプルプロジェクトを見ると、

きれいなお部屋の中を歩き回ることができます。

f:id:r-ngtm:20201220090636j:plain

 

このお部屋、竹の根元に蝶々がいます。かわいい。

f:id:r-ngtm:20201220093011g:plain

蝶々

 

この蝶々はVFX Graph で作られています。

f:id:r-ngtm:20201220093308p:plain

VFX Graph

 

今回は この VFX Graphを読んでいきたいと思います。

 

Inspector上の設定

Visual Effect コンポーネントを見ると、以下のような設定になっています。

f:id:r-ngtm:20201220093710p:plain

Visual Effect コンポーネント

 

Rendering Layer Mask

Rendering Layer Maskの部分が Mixed... になっているのが気になります。

f:id:r-ngtm:20201220093900p:plain

Rendering Layer Mask

f:id:r-ngtm:20201220093954p:plain

二つのLayerのチェックがONになっている

Rendering Layer Maskを変えてみる

蝶々を拡大すると、以下のような表示になっています。

f:id:r-ngtm:20201220094639p:plain

初期設定

 

Rendering Layer Mask を Decal Layer default のみ有効にすると、白っぽい感じになります。

f:id:r-ngtm:20201220094555p:plain

Light LayerDefault を有効にすることで、VFXの描画結果がライトの影響を受けるようになるみたいです。

 

Light LayerDefaultのみをONにすると以下のような表示になります。

f:id:r-ngtm:20201220094918p:plain

Light LayerDefaultのみに設定



Properties

続いては、Propertiesを見てみます。

f:id:r-ngtm:20201220095208p:plain

Properties

パラメータは以下のようなものを表しているようです。

 

プロパティ 意味
Count 蝶々の生成数
Radius 蝶々を生成する位置の半径
Wing Animation Speed 蝶々の羽ばたくアニメーションの速さ

VFX Graphのプロパティからアニメーションを制御できるのが興味深いと思いました。

 

VFX Graphの中を見てみる

次は、VFX GraphアセットButterFliesの中を覗いていきます。

VFX Graph

コンテキスト

ButterFlies アセットの中身は以下のようになっています。

VFX Graph の 4つのコンテキスト
コンテキスト やっている内容
Spawn 蝶の生成
Initialize 蝶の初期化
Update 蝶を動かす
Output 蝶を画面に出す

 

Spawn

Spawn コンテキストでは、 Single Burst ブロックが使用されています。

VFX開始時に、一度だけ Count 分の蝶を生成しています。

Spawn コンテキスト

 

Initialize Particle

その次の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ブロックでは、位置と外積を利用して、球に沿って下方向へ向かうような向きを設定しています。

やっていることがやや複雑なので紐解いていきます。

SetDirectionブロック

Set Directionへ設定しているベクトルデータ(Houdiniで可視化)

 

 

 

Get Attribute : position current

Get Attribute は パーティクルが持つ情報(Attribute)を取得するノードです。

今回は position currrent(現在の座標)を取得しています。

 

今回、蝶(パーティクル)は球の内部にまばらに存在しています。

Houdiniを使って可視化してみると、以下のようになるでしょうか。

球の内部にまばらに存在する点

 

Normalize (Vector3)

Normalizeはベクトル長を1にする(正規化)を行うノードです。

Normalize で 座標を正規化

 

座標にNormalizeをかけると、点は半径1の球の表面に並びます。

 

Cross Product (Vector 3)

Cross Product は ベクトルの外積を行うノードです。

Cross Product

 

外積結果を黄色い線として、表示してみると以下のようになります。

時計周りの向きになります。

 


さらにこのベクトルを、元の座標と外積しています。

座標とベクトルの外積

ベクトルの計算結果は以下のようになります。

球に沿って下方向に向かうベクトルになりました。

ノードだけを見るとなかなかイメージがつかみにくいですが、可視化すると分かりやすいですね。

最終的に得られるベクトル

 

このベクトルは、Set Direction ブロックへ入力されます。

つまり、蝶は最初は下を向いているということになります。

Set Direction へ入力

 

実際のノードと、ベクトルの可視化を並べてみました。

ノードとベクトルの対応

 

Set Tex Index

Set Tex Index ブロック

この蝶々の元素材は以下のようなテクスチャシートになっています。

蝶々の元素材

 

Set Tex Indexブロックでは、テクスチャシートの左から何番目のテクスチャを使うか、という番号を設定した物になります。

 

Add Velocity from Direction & Speed (Random Direction)

このブロックは、パーティクルのDirectionの方向に対して、ランダムな速度を加算しています。

先ほど、Set Direction ブロックにて以下のようなベクトルを設定していたので、

球に沿って下方向に対して、長さ0.2 ~ 1.0 のランダムな速度が足されることになります。

Add Velocity ブロック

 

加算される速度の向き

以上で Initialize Particle コンテキストは終わりとなります。

次に Update Particle コンテキストを見ていきます。

 

 

Update Particle コンテキスト

Update Particle コンテキスト

Updateコンテキストでは、以下のようなブロックが接続されています。

 

ブロック やっている内容
Force 力を足す
Turbulence 速度に乱流を与える
Set Velocity 速度が0.5を下回らないように制限を加える
Set Scale.XY パーティクルの大きさの設定

Set Pivot.X

メッシュのピボットを設定 (メッシュの回転の中心位置を決める)

 

Force

Forceブロックでは、蝶にかかる外力を設定しています。

Forceブロック

 

PositionとDirectionの外積

PositionとDirectionの外積

ノードだけ見てもよくわからないので、Houdiniを使って可視化してみます。

 

Direction

Initialize コンテキストにて設定したDirectionですが、

時間が経過するとパーティクルは移動し、以下のようにバラバラな向きになります。

どのパーティクルも、下方向になっています。

 

 

PositionとDirectionの外積をとると、球に沿ったベクトルになります。

つまり、原点(0,0,0)の周りをグルグル回るようなベクトルになります。

別の角度から見た場合

 

横方向ベクトルへランダム値を乗算

ここで求めた横方向ベクトルに、パーティクルごとのランダムな数値を乗算し、

速度に揺らぎを持たせています。

ランダム値の乗算

中心へ向かう引力

先ほどにベクトルに対して、座標(position) の符号を反転したものを加算しています。

これは原点へ向かって引き寄せる力になります。

符号反転した座標を加算


座標は正規化せずに符号反転したものを使っているので、

パーティクルが原点から離れるほど強い引力になり、

パーティクルが原点に近づくと弱い引力になります。

中心へ向かう引力

最終的には以下のようなベクトルが外力となります。

横方向ベクトルを灰色、 中心へ向かうベクトルを黄色で表しています。

中心へ向かう引力(黄色) と 回転の力(灰色)

 

Turbulence

Turbulenceブロックではパーティクルに乱流を与えるもので、

蝶の動きに揺らぎを与えます。

Turbulenceブロック

Set Velocity

Set Velocityはパーティクルの速度を上書きするものです、

パーティクルの速さ(VelocityのLength)が0.5を下回らないように制限を与えています。

Set Velocity

Set Scale / Set Pivot

ここでは、パーティクルのスケールやピボットを設定しています。

0.45や0.6という謎の数字が登場しますが、アートの都合によってこのような数値になったのだと思います。

Set Scale / Set Pivot

 

Set Pivotを外してみた

通常の蝶はこのような表示になっていますが、

蝶の表示

Set Pivot を無効にすると、以下のようないびつな表示になってしまいます。

 

 

以上でUpdate Particleは終わりとなります。

次にOutput 系のコンテキストを見ていきます。

 

Output コンテキスト

Output Particle Lit Quad

 

Orient Adnvanced (羽の向きの設定)

パーティクルの向きの設定は Orient Adnvanced ブロックで行っています。

向きの設定

 

Axis Z、Axis Y の挙動について

Axis Z や Axis Y を設定した際のメッシュの向きは以下のようになります。

メッシュの面はAxisZを向き、メッシュの上方向はAxisYに一致するようにメッシュ自体が回転します

 

Z軸を変えた時のパーティクルの向き

 

f:id:r-ngtm:20201220160138p:plain

Y軸を変えた時のパーティクルの向き

ちなみに、パーティクルのローカルのX軸(赤い線)は, Axis Z と Axis Y外積に一致しています。

パーティクルのX方向はZ, Y の外積に一致

 

蝶の羽の向き

今回の蝶パーティクルのAxis は以下のように設定されています。

  • Axis Z : 進行方向に対して横向き
  • Axis Y : 上方向

蝶の羽メッシュとAxisの対応関係

向きの設定

 

蝶のはばたき

蝶の羽ばたきは、Add Potision や Set Angle.Y によって実装されています。

Y方向の位置変化(Add Position) + 羽の回転(Set Angle.Y) をSine波で動かすことで羽ばたきを表現しています。

Add Position / Set Angle.Y

 

羽ばたきの実装

 

羽ばたき

Sine波が大きくなると、羽が大きく広がり、蝶も早く移動するような実装になっています。

Angle.Y = 0 だと、羽が完全に閉じた状態になります。

Angle.Y = 0の場合

 

Set Angle.X

最後のSet Angle.X は、羽のX回転を設定しています。

Set Angle.X

以下のような軸で回転します。

回転の軸

 

関連

Unity 2020.2 TECH ストリームがダウンロード可能になりました

Unity 2020.2 TECH Stream is now available for download (unity3d.com)