トランジスタスタジオ・秋元純一氏によるHoudini連載「Houdini Cook Book Entry」。Houdiniをより基礎の部分から解説し、最後にはふり返りとして課題も用意しています。第6回はVDBを使った侵食のシミュレーションについて解説します。


秋元純一 / Junichi Akimoto
株式会社トランジスタ・スタジオ/取締役副社長
2006年に株式会社トランジスタ・スタジオ入社。日本でも指折りのHoudiniアーティスト。手がけてきた作品は数々の賞を受賞している
要素をいかに組み合わせてアプローチを設計するか
前回に引き続きSolver SOPを使用したシミュレーションを紹介していきたいと思います。
Solver SOPを使用したシミュレーションは、前回のような単純なものでも、プロシージャルなモデリングにシミュレーションを使用するようなアプローチは非常に有効です。また、VDBを自在に扱えるようになること自体、今後のHoudiniライフを豊かにすることは間違いありません。
Houdiniにおいて重要な考え方のひとつとして、アプローチを全体で考えると同時に、それぞれのブロックを分離した“オブジェクト”としてとらえ、どう組み合わせるかを練って設計することが、肝になってきます。
ひとつひとつのアプローチ自体は単純ですが、そのブロックの組み合わせ次第では、非常に複雑なものとして成立させることができるのもHoudiniの大きな魅力だと言えるでしょう。
01 All Flow / 全体のながれ

STEP 01
まず初めに、ベースとなるジオメトリを読み込みます【A】【1】。
STEP 02
このジオメトリをVDB From Polygons SOP【B】でDistance VDBへコンバートします。最初のテスト時から高解像度にせずに、動きを確認してから最終的な解像度にすることをオススメします【2】。
STEP 03
次に、Solver SOP【C】を使用して侵食のシミュレーションを行なっていきます。
読み込まれたVDBにVDB Analysis SOP【D】を使って、GradientでScalarからVectorへ変換します【3】。このとき、"vel"というカスタムネームを指定しておきます【4】。実際、この名前でなくてはいけないという指定はありませんが、今回はわかりやすくこうしています。


STEP 04
次に、Volume VOP【E】を使って、作成した"vel"をカスタマイズします。


作成した"vel"をBind VOP【F】で読み込みます。このときつくられているVectorは外向きになるので、Negate【G】で反転しておきます。

STEP 05
次に、Turbulent Noise VOP【H】を組み合わせて、侵食するエリアを指定します。このノイズで作成された数値は、負の値が入ってしまうので、Clampしておくと良いでしょう【I】。
この値を"vel"にかけ合わせ、また値の強度をParameterで調整できるようにしておきます。最後にBind VOPで出力して完了です。

STEP 06
続いて、VDB Advect SOP【J】を使って、作成した"vel"の方向へVDBを変化させます。
VDB Advect SOPはVector VDBの情報を基に、その方向へVDB DistanceもしくはFogを動かすことができます。ただし、このノード自体はフィードバックループをしないので、時間軸に沿った動きをしてくれるわけではなく、今回のようにSolver SOPを使用してアニメーションを作成します。これでシミュレーションをかけて、一度キャッシュを取ります【5】。
STEP 07
キャッシュされたVDBを、Convert VDB SOP【K】でPolygonへ変換します【6】。
STEP 08
次に、VDB Combine SOP【L】を使って、シミュレーション後とシミュレーション前のVDBをSubtractで計算します【7】。
STEP 09
また、VDB From Polygons SOP【M】をコピーして、このノードではFill InteriorでVDBの内部を満たします【8】。これはシミュレーション前にこの情報をもっていると余分に重くなるため、あえて別途作成しています。


STEP 10
これらの情報を基に、VOP【N】でAttributeを作成していきます。


Volume Sample VOP【O】を使って、インプットのそれぞれのVDBを読み込みます。ここで得られる情報は、SDFの特徴である、符号付きの距離です。実際のジオメトリの表面からの距離を計測できるので、その情報を基にAttributeを作成していきます。

まず、侵食されたエリアを指定します。今回は、入力された数値に対して、Compare VOPとTwo Way Switch VOP【P】を使って指定した数値と比較して、白黒明確に分けたAttributeを作成しました。この方法に準じたアプローチは様々ありますが、簡易的にこのようにしています【9】。
STEP 12
次は、侵食の深度を計測します。Fill Interiorで埋めたVDBを使って、単純に深度を計測し、それをFit Range VOP【Q】で調整します【10】。
これでレンダリング時にマスクなどで活用できるAttributeを作成することができました。必要に応じてAttribute Blur SOP【R】などでぼかして調整すると良いでしょう。 その他にも、このエリアを使って他のシミュレーションなどを追加作成することができます。

02 Hints / 制作に役立つヒント
VDBの種類とそのサンプリング
VDBを使用する上で、その特性を理解しておくことは非常に重要です。これまで何度か登場したVDBですが、深く語るには多くのページが必要になるでしょう。それくらい、CG業界でのオープンソースとして重要な要素になっていると言えます。
特に重要な基礎としては、FogとDistanceです。Fogは、主に密度を表すためのVDBです。例えば、煙の濃淡は、このFogの密度を利用しています。ただ、それだけではなく、Scalar値としての特性を活かして、温度などにも利用することが可能です。1つのボクセルにはFloatの値が入っていると認識していればまずは大丈夫です。
次に今回使用したDistanceです。これはSDFとも呼ばれるものですが、符号付き距離関数なんて言い方もします。元々のサーフェス表面を0とした際に、そこからの距離を数値でもっているものです。
画像は、サーフェス表面を起点に、マイナス値からプラス値に向けてグラデーションを作成した例です。 その他にも、Vectorの値をもてるのもVDBの特徴で、その軽量さを活かして、モデリングに有効活用できるのも魅力のひとつですし、当然、ハイディテールを求めることも以前より簡単になりました。

03 Issues / 今回の課題
Issue 01:継続的な切断 / Effect ★☆☆☆☆
溶接で切断しているようなエフェクトを作成してみましょう。
ヒント:これまでの経験値を活かせば非常にシンプル。 VDBの論理演算が肝です
Issue 02:Particleの衝突 / Effect ★★★☆☆
Particleの衝突を計算してみましょう。
ヒント:前回に引き続きParticleをSolver SOPで作成し、それに衝突の簡単な計算を行なってみましょう。 Volume Sample Vector VOPがポイント
こちらの制作例は、今回のプロジェクトデータ内に用意しています。ひととおり制作できたら、ぜひ確認してみてください。
今回のプロジェクトデータはこちらから>>TEXT_秋元純一 / Junichi Akimoto
EDIT_小村仁美 / Hitomi Komura(CGWORLD)