【Houdini】VDB Morph SDFでトポロジー無視のモーフィングを行う

eyecatch
eyecatch

目次

はじめに

無性にジオメトリをモーフさせたくなるときってあるよね.
冒頭の画像を作るときに初めてVDBMorphSDFを使ったので使い方をメモっておく.
あくまでメモなので,もっといい方法があるかも.悪しからず.
↓本記事ではサンプルとしてこれを作る (サンプルデータ)

morph
morph

メッシュのVDB化

トポロジーを無視してモーフするといえど,ある程度形状が似ているオブジェクト同士の方がモーフしてる感 (?) が出る.
PigHeadとTemplateHeadを配置してVDBに変換する.今回はVoxel Sizeを0.005とした.
TransformとPolyFillはスケールとメッシュを調整するためのもの.テストジオメトリのスケールぐらい揃えといてくれよ

2021-03-01T215814
2021-03-01T215814

2021-03-01T215930
2021-03-01T215930

モーフのシミュレーション

Solverに2つのVDBを接続する.

2021-03-01T220059
2021-03-01T220059

Allow Chaching To Diskにチェックを入れておくとシミュレーション結果がメモリの上限値を超えてもディスクに保存してくれる.ここではチェックを入れておく.

2021-03-01T221444
2021-03-01T221444

Solver内でVDBMorphSDF (公式ヘルプ) にPrev_FrameとInput_2を接続する.パラメータは触らない.

2021-03-01T220626
2021-03-01T220626

Solverに表示フラグを立てて1からフレームを進めるとモーフのシミュレーションが計算される.

morph01
morph01

しかし今回はモーフが完了する前にフレームの最後 (240frame) にたどり着いてしまった.この解決法は以下の3つ (他にもあるかも)

  • FENDを伸ばす
  • SolverパラメータのSub Stepsを増やす
  • VDBMorphSDFパラメータのTimeStepを増やす

どれでもいいけど,今回は2番目の方法で行う.Sub Stepsを3にして再度計算を行う. (当然1フレームあたりの計算量は多くなる)

2021-03-02T210704
2021-03-02T210704

これで最後までモーフするようになった.

morph02
morph02

File Chacheを繋いでSave To Diskし,計算結果を保存しておく.今回はたまたまフレームの最後でモーフが完了したので保存するFrame Rangeはデフォルト値のままだが,もっと早く終わったならそれに応じて保存期間も短くしたほうがディスクを無駄に消費せずに済むと思う.

2021-03-01T232539
2021-03-01T232539

2021-03-01T232729
2021-03-01T232729

保存したらLoad From Diskにチェックを入れておく.
本来ならシミュレーションとその結果の利用でジオメトリを分けたほうがいいけど今回は省略.

2021-03-01T233149
2021-03-01T233149

モーフをパラメータから制御する

現在はフレームによってモーフィングしているが,これをパラメータから制御できるようにしたい.
まず制御用のNullを作成し,morphという名前の0~1のfloatパラメータを追加する.

2021-03-01T233736
2021-03-01T233736

次にTime Shift (公式ヘルプ) を接続する.

2021-03-01T233929
2021-03-01T233929

これは入力ジオメトリの任意の時間での状態を出力するノード.デフォルトではFrameに$Fが入っているため,現在のフレームのジオメトリの状態がそのまま出力される.

2021-03-01T234136
2021-03-01T234136

このFrameの値を以下に書き換える.

1
fit(ch("../Controller/morph"), 0, 1, $FSTART, $FEND)

Controller morphパラメータの値 (0~1) とシミュレーションの初めから終わり (FSTART~FEND) をfit (公式ヘルプ)で対応させているので,morphパラメータに応じてモーフするようになった.

morph
morph

最後にConvert VDBでメッシュ化すれば完成.

2021-03-01T235750
2021-03-01T235750

おわりに

厳密に言うとSolverの1フレーム目から既にモーフが始まっているため,morphパラメータを0にしていても若干 (変形シミュレーション1フレーム分) 形が崩れていたりする.
これに関してはSolverのStart Frameを2にして$F = 1のときだけswitchで変形元のVDBをキャッシュに出力するとか工夫が要る.

あとモーフの変化量がステップで等しくないため,初めらへんは急激にモーフして最後らへんはゆっくりめになる. (モーフするジオメトリにもよるが)
そのためモーフに緩急をつけたアニメーションを付けたいときとかはこのままだとちょっと面倒かも.
fit(pow(ch("../Controller/morph"), 1.5), 0, 1, $FSTART, $FEND) みたいにコントローラの値を補正してやるといいかも.

関連・参考文献