目次
はじめに
無性にジオメトリをモーフさせたくなるときってあるよね.
冒頭の画像を作るときに初めてVDBMorphSDFを使ったので使い方をメモっておく.
あくまでメモなので,もっといい方法があるかも.悪しからず.
↓本記事ではサンプルとしてこれを作る (サンプルデータ)
メッシュのVDB化
トポロジーを無視してモーフするといえど,ある程度形状が似ているオブジェクト同士の方がモーフしてる感 (?) が出る.
PigHeadとTemplateHeadを配置してVDBに変換する.今回はVoxel Sizeを0.005とした.
TransformとPolyFillはスケールとメッシュを調整するためのもの.テストジオメトリのスケールぐらい揃えといてくれよ
モーフのシミュレーション
Solverに2つのVDBを接続する.
Allow Chaching To Diskにチェックを入れておくとシミュレーション結果がメモリの上限値を超えてもディスクに保存してくれる.ここではチェックを入れておく.
Solver内でVDBMorphSDF (公式ヘルプ) にPrev_FrameとInput_2を接続する.パラメータは触らない.
Solverに表示フラグを立てて1からフレームを進めるとモーフのシミュレーションが計算される.
しかし今回はモーフが完了する前にフレームの最後 (240frame) にたどり着いてしまった.この解決法は以下の3つ (他にもあるかも)
- FENDを伸ばす
- SolverパラメータのSub Stepsを増やす
- VDBMorphSDFパラメータのTimeStepを増やす
どれでもいいけど,今回は2番目の方法で行う.Sub Stepsを3にして再度計算を行う. (当然1フレームあたりの計算量は多くなる)
これで最後までモーフするようになった.
File Chacheを繋いでSave To Diskし,計算結果を保存しておく.今回はたまたまフレームの最後でモーフが完了したので保存するFrame Rangeはデフォルト値のままだが,もっと早く終わったならそれに応じて保存期間も短くしたほうがディスクを無駄に消費せずに済むと思う.
保存したらLoad From Diskにチェックを入れておく.
本来ならシミュレーションとその結果の利用でジオメトリを分けたほうがいいけど今回は省略.
モーフをパラメータから制御する
現在はフレームによってモーフィングしているが,これをパラメータから制御できるようにしたい.
まず制御用のNullを作成し,morphという名前の0~1のfloatパラメータを追加する.
次にTime Shift (公式ヘルプ) を接続する.
これは入力ジオメトリの任意の時間での状態を出力するノード.デフォルトではFrameに$F
が入っているため,現在のフレームのジオメトリの状態がそのまま出力される.
このFrameの値を以下に書き換える.
1 | fit(ch("../Controller/morph"), 0, 1, $FSTART, $FEND) |
Controller morphパラメータの値 (0~1) とシミュレーションの初めから終わり (FSTART~FEND) をfit (公式ヘルプ)で対応させているので,morphパラメータに応じてモーフするようになった.
最後にConvert VDBでメッシュ化すれば完成.
おわりに
厳密に言うとSolverの1フレーム目から既にモーフが始まっているため,morphパラメータを0にしていても若干 (変形シミュレーション1フレーム分) 形が崩れていたりする.
これに関してはSolverのStart Frameを2にして$F = 1
のときだけswitchで変形元のVDBをキャッシュに出力するとか工夫が要る.
あとモーフの変化量がステップで等しくないため,初めらへんは急激にモーフして最後らへんはゆっくりめになる. (モーフするジオメトリにもよるが)
そのためモーフに緩急をつけたアニメーションを付けたいときとかはこのままだとちょっと面倒かも.fit(pow(ch("../Controller/morph"), 1.5), 0, 1, $FSTART, $FEND)
みたいにコントローラの値を補正してやるといいかも.