VRChatでHoudiniのVATを使う(SoftBody/Fluid編)

#VATとは?
VertexAnimationTextureの略でメッシュのアニメーションをテクスチャとして出力しUnityで再生する手法です。
事前にアニメーションを計算しておくことで流体のような複雑なシミュレーションや大量のオブジェクトの動作を比較的軽量に実現できます。
VRChat(Quest版含む)でも動作するので他では作れない演出ができます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ケーブルにょろにょろがVRCでも動いた <a href="https://t.co/w4W0AsEyYD">pic.twitter.com/w4W0AsEyYD</a></p>&mdash; なまのなまこ (@Iiron_Lung) <a href="https://twitter.com/Iiron_Lung/status/1377105963962933248?ref_src=twsrc%5Etfw">March 31, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

アニメーションのパターンによって種類があり、今回はSoftBodyシミュレーションについて扱います。
メッシュ形状は変化するがトポロジーは変化しないというパターンで、布などやわらかい物に使うことができます。

FluidはSoftBodyと似たような手順のため解説は省略します。
サンプル・シェーダーは各リポジトリに含めています。
トポロジーが変わるような場合に使うもので、液体のようにメッシュがちぎれたりするものでも出力できます。

RigidBodyはこちら
[VRChatでHoudiniのVATを使う(RigidBody編)](https://qiita.com/namanonamako/items/ff11b5a135102f9259c1)

#環境
VRCSDK2-2021.03.22.18.27
Houdini　18.5.499

VRC_SDKをインポートする前後でプロジェクトの設定が変わるので、必ず確認しましょう。
この記事の説明はVRC_SDKインポート済みを想定しています。
<font size =1 color="Silver">軸や色空間が変わるようです。このあたりシェーダー内の回避策がわかる人いたら教えて下さい</font>

Houdiniは無償ライセンス版も存在しますが、VAT用テクスチャにウォーターマークが入るためアニメーションが乱れます。

本記事のサンプルプロジェクトは[こちら](https://github.com/namanonamako/VATforVRChat)

#リソース
VRChat向けに手を加えたVAT用シェーダーをGithubで公開しています。
こちらのunity/shadersフォルダを自分のUnityプロジェクトに配置してください。
調整中で不具合が残っているかもしれませんので、改善方法があれば連絡いただければ幸いです。

https://github.com/namanonamako/SideFXLabs

#Houdiniでアニメーションを作る
豚に布をかけましょう。
まずはGridを準備。分割などしておきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495102/e4cd7a9b-5049-d885-39ec-e6f8170573e2.png" width=60%>

objレベルに戻って上部ツールから`Vellum>VellumCloth`を選択。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495102/eb6ba679-0dcd-a1e3-8b65-26c8d472d355.png" width=30%>
自動的にシミュレーションが作成されます。
そのままでは無限に落下してしまうので最初にGridを作ったGeometryノードに戻り`testgeometry_pighead`ノードを追加。
`AutoDopNetwork`ノード内で`staticobject`ノードを追加。`vellumobject`に`merge`します。
`staticobject`の`SOP Path`に先ほど作った`testgeometry_pighead`を指定し、再生ボタンを押すとシミュレーションが始まります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495102/e78a6ce3-a74a-4d23-430c-8b972e34c6dc.png" width=80%>



#HoudiniからVATを出力
作ったアニメーションをVATで出力します。
SOP(/obj)からROP(/out)へ移動し`vertex_animation_textures`ノードを作成します。

各項目の設定
`Start/End`：出力するアニメーションのフレーム指定
`Method`：VATの種類　今回はSoftを指定します
`Engine`：Unityをえらび必ず`Initialize Engine`を押す
`SOP Path`：出力するアニメーションノードのパス  /obj/cloth_vellum/vellumpostprocess1を選びます
`Pack normals into Position Alpha`：ノーマルをPosテクスチャのアルファに焼くか別テクスチャで出すか。どちらでもいいと思います。とりあえず入れておきます。
`Target Texture Size`：ポリゴンやフレームが多い場合は大きくしておくといいと思います。
`Paths`：必要な出力物にチェックをつけましょう。今回MaterialとRealtimeDataはいらないので外しておきます。

設定ができたら`Render`ボタンを押して出力
こんな感じになりました。
後でUnity側で値を使うのでHoudiniは閉じないでおきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495102/7c506bc8-9407-1114-e86b-c7159e927646.png" width=60%>

#Unityに導入
指定したパスにテクスチャとメッシュが出力されているのでUnityのプロジェクトに導入します。
vertex_animation_textures1_mesh.fbx
vertex_animation_textures1_pos.exr

導入したテクスチャのインポート設定を変更します。
VATは頂点位置を色として読み書きするので圧縮などされると動きが変わってしまうからです。
`AlphaSource`はHoudini書き出し時の設定に合わせます。
今回は出力時に`Pack normal into Position Alpha`を使っているのでInput Texture Alphaにします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495102/9501f874-9a03-113c-0db0-5b670a0a585f.png" width=60%>

Meshをシーンに配置してマテリアルを割り当てます。
Materialのシェーダーは上記URLからダウンロードした`"sidefx/vertex_soft_body_shader"`を選択。
PositionMapに出力されたテクスチャを指定します。

マテリアルの各項目はHoudiniの数値を持ってきます。
NormalをAlphaに焼いたのでPackNormalにもチェックを入れましょう。

|Houdini  |Unity  |
|---|---|
|Position Min/Max  |Bounding Max Min  |
|Frame Range  |Number Of Frames  |
|Speed  |Speed  |

OK！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495102/2e5fbe50-f875-84d0-6351-5dfa87c28dfa.gif" width=60%>

VATはシェーダーで見た目だけを動かしているのでメッシュの実体は初期位置のままです。(オレンジ枠線部)
カメラを動かして破片が消えてしまうときはMeshRenderをSkinedMeshRenderに変えてBoundsを大きくしてみてください。
また、同じ理由からMeshColliderなども追従しません。

#おわりに
パラメーターが多く繊細なので変な動きをする場合は設定を見直してみてください。
他の種類のVATも順次追加予定です。

#動かないとき
- テクスチャの設定を見直す  
`Max Size`や`Alpha Source`など設定を変えてみるとうまくいくことがあります
- `Engine`の設定  
Unityを選んだ後に`Initialize Engine`の押し忘れがあると動く向きがおかしくなります
- エクスポート時のエラー
HoudiniのプロジェクトによってはVATエクスポート時にエラーになるようです。(原因不明)同じノード設定を新規プロジェクトで試すと出力できるかもしれません。