前回に続き、今回はHoudiniを用いてサメの水やしぶきのシミュレーションの解説をしていきます。
連載「PHENOMENAL THINGS」最終回
Houdiniを用いてサメの水や飛沫のシミュレーションを制作していきます。そしてこの連載「PHENOMENAL THINGS」は今回で最終回です。約7年間のご愛読ありがとうございました。またちがうかたちで作品の解説など提供していけたらと思います。
<1>ZBrushで作成したサメのモデルを読み込む
前回ZBrushで作成したサメのモデルを読み込みます。体と目の2パーツをマージし、トランスフォームを調節します。
<2>サメにアニメーションを付ける
サメにアニメーションを付けます。まずはSkeletonノードでボーン「KineFX」を作成。
<3>ウェイトを付ける
次にウェイトを付けます。Houdiniではカーブをボーンとして使用し、ジョイント(カーブのポイント)を動かしたり物理シミュレーションと組み合わせて、プロシージャルにアニメーションを付けることができるKineFXがとても便利です。RigPoseノード内でジョイントを回転させながら、BoneDeformノードで実際にジオメトリがどのように変形しているかを確認しつつアニメーションを付けました。
<4>Velアトリビュートを作成
続いて、アニメーションを付けたジオメトリからFlipシミュレーションに使用するVelアトリビュートを作成します。Trailノードで次フレームから計算されたvアトリビュートを基に、ノイズなどを少し加え、それをVolume Rasterize AttributeノードでVolume用のアトリビュートVelへ変換し作成しました。別フローで水に対するコリジョン用のVDBを作成しておきます。
<5>流体シミュレーションを作成する
流体シミュレーションを作成します。FlipTank、DOP Network、FlipTank Fluid Surface用のジオメトリノードをそれぞれ作成します。OceanSourceノードで水面の初期値を設定し、それをParticlesとSurfaceへフローを分けOUTします。
<6>DOP Network内で水のシミュレーションを行う
DOP Network内で水のシミュレーションを行なっていきます。FlipObjectノードとFlip Solverノードで、先ほど作成したParticlesとSurfaceを対象に処理します。
POP Dragノードは、水が飛び散りすぎないように空気抵抗を加えるノードです。VelアトリビュートはVolumeSourceノードにて読み込みます。StaticObjectでは先ほど作成したサメのVDBを設定して、水へのコリジョンオブジェクトとします。VDBですのでVolumeSampleモードに変更しておきます。
<7>シミュレーション後の水をポリゴン化する
DOPでのシミュレーションができたら、続いてFlipTank Fluid Surfaceジオメトリノード内で、シミュレーション後の水をポリゴン化します。FluidCompressノードで全てのFlipデータを圧縮しつつ、それをFile Cacheで保存しておきましょう。
解像度の高い流体のキャッシュ保存には膨大な時間がかかりますが、PCスペックと相談しつつディテールとキャッシュ時間を調節しましょう。Particle Fluid SurfaceノードでCompressしたデータをサーフェス化します。こちらも同様に再生に時間がかかるのでキャッシュしておきましょう。サーフェス化が終わったら、次はホワイトウォーター(しぶきや泡)を作成します。
<8>Whitewaterもそれぞれの別ジオメトリノードを作成
WhitewaterもFlipTankと同様にSource 、DOP、OUTそれぞれの別ジオメトリノードを作成しておきます。
<9>Whitewater Sourceノードで飛沫の初期値を設定
WhitewaterにはFluidCompressのデータが必要なので、Object Mergeノードで先ほどキャッシュをとったCompressノードを読み込みます。Whitewater Sourceノードで飛沫の初期値を設定します。
<10>DOPノード内のWhitewater SolverにWaterObjectを挿す
DOPノード内のWhitewater Solverに今作成したWhitewater Objectを挿します。そしてVolume SourceをCompress Cache、Emission SourceをWhitewater Sourceに設定しましょう。Static Objectノードには、FlipTank時と同様にサメのVDBをコリジョンオブジェクトとして設定します。
<11>Whitewate rOutジオメトリノード内でシミュレーション結果を読み込む
DOPでのシミュレーションが完了したら、Whitewater Outジオメトリノード内でシミュレーション結果を読み込み、同様にキャッシュを取っておきましょう。
<12>再生結果を確認する
再生してみるとこのような結果になりました。クオリティはWhitewaterパーティクルとCompressデータの解像度に依存しますので、何度かトライ&エラーを繰り返す必要があるかもしれません。
<13>現時点のパーティクルを様々な用途で使用する
現時点ではパーティクルなので、これを基にVolumeへ変換したり、Particleとしてレンダリングしたりと使用できる用途は様々です。VDBへ変換して飛沫のフォグとしてレンダリングするために、ここではVDB CombineノードとVDB AnalysisノードでVelアトリビュートの統合とScalar化を行なっています。
<14>パーティクルとしてレンダリングするための準備
別フローで、パーティクルとしてレンダリングするためのPscale値とPointReplicateノードでのポイント複製を行なっています。
<15>「Mist」という別のフォグを作成
さらにWhitewater ParticleからVolumeへ変換しPyroSolverに繋いで、「Mist」という別のフォグも作成しておきます。
<16>泡としてレンダリングできるよう用意する
Whitewaterを作成すると「Foam」という泡を示すアトリビュートが生成されますので、それらのみをGroupとBlastノードで取得し、泡としてレンダリングできるよう用意します。
<17>泡の部分もポイントの密度を調節する
泡の部分も別途Pscaleやポイントの密度を調節します。
<18>ポリゴンに泡のシェーダを割り当ててレンダリング
それらのポイント群をVDB From ParticlesでVDBへ変換し、さらにポリゴン化します。このポリゴンには泡のシェーダを割り当て、ポリゴンとしてレンダリングします。
<19>準備完了
これで「水面の水のシミュレーション」「飛沫のシミュレーション」「飛沫のボリュームデータ」、さらには「泡のボリューム」「泡のポリゴンデータ」を準備できました。
<20>ライトとシェーダを設定してレンダリング
最後にライトとシェーダを設定し、レンダリングして完成です。今回もRedshiftでのレンダリングを行いました。
<完成>
![](/regular/fixed.jpg)
![](/regular/445554438e83bd2fb1d263591527497d8b00b9b5.jpg)
森田悠揮 / Yuuki Morita
フリーランスキャラクターデザイナー/デジタルアーティスト/造形作家
国内外問わずアート、映画、ゲーム、広告、デジタル原型など様々なジャンルで活動しているフリーランスのアーティスト。ZBrushでの生物や怪獣などのクリーチャーデザインを得意とする傍ら、Houdiniを用いた動画、アート制作なども行う。初の著書 『the Art of Mystical Beasts』ボーンデジタルから発売中。
website: itisoneness.com
Instagram: yuukimorita
Twitter: @YuukiM0rita
TEXT_森田悠揮 / Yuuki Morita(@YuukiM0rita)
EDIT_三村ゆにこ / Uniko Mimura(@UNIKO_LITTLE)