『Houdini Fluid Simulation セミナー』


2018年4月21日(土)に、浜松町のKCDホールにて、『Houdini Fluid Simulation セミナー』が開催されました。

 

こちらのセミナーでは、Houdini FX スーパーバイザー兼 アーティストの都築 賢人 様より、HoudiniのFluid Simulation、そしてその中に含まれるMicroSolverの基本的なワークフロー、シミュレーションのパフォーマンスの最適化の方法とその事例をご紹介頂きました。

まず最初は、Houdini のDOPを使用したFluid Simulationの一般的な流れについてのご紹介です。Simulationを各種パラメータで設定し、炎や煙といったSimulation Modelを表現し、OpenVDB等の形にOutputするというのが、一番大きな流れです。

Simulation Modelは、DOP内に入力されたもしくは作成されたFieldのデータに対してSolverを実行し、結果をループするか、終了し、出力する流れになっています。このSimulationModelをHoudiniのネットワークの見た目に近づけると、上記の画像左側のように、Simulation ObjectExtra ForceSourceが入力されたSolverという形であらわすことができます。

Simulation Objectは、シミュレーションの計算に使用されるFieldのデータを格納するものを指し、Solverは、入力されたデータを基に作成し、どのように運用するかという操作を行うためのもの、Sourceは、時間軸にそって変化させたいFieldがある場合にそのデータを管理するためのもので、Extra Forceは、デフォルトのSolverでは扱えないものを扱えるようにするための拡張機能のようなものです。「Extra Force」、「Source」、「Solver」の大半は、Field Simulationのアルゴリズムをノードとして使えるようにしたMicroSolverで構成されています。

 

次に、パフォーマンスアップを行うために知る必要のある、Basic Houdini Volumetric Solver の構造についてご紹介頂きました。

上記の画像が、基本的な構造を図にしたものです。

Sourcingが、Density、Velocity等を時間軸に沿って更新を掛ける処理で、ここからの情報をDOP内にインポートした後は、VelocityをVelocityで移流させるAdvect Velocity

流体らしいVelocityに変換するDivergence Free、3Dグリッドで衝突判定を設定するBoundary Setting、煙のアニメーションを実行するDensity Advectがそれぞれ処理され、終了判定まで繰り返し、VBD Volume へExportするという流れになっています。

この流れは、Solverの拡張や応用を行うときに、どの部分を編集すれば良いかを理解するときに、重要になってきます。このほか、アーティストがどの部分に変更を加えるのか、またDivergence設定についてもご紹介頂きました。

 

その後、上記のフローでのSolver のパフォーマンスに関して、計算が重くなる原因、問題点と、改善方法についてご紹介頂きました。まず、上記ワークフロー内の計算コストがかかる部分はSourcing 、Advect Velocity、Divergence Free、Outputで、この部分が高解像度になるとSimulation開始までに時間がかかる原因になっています。

上記のフローは通常順番に処理を行っていますが、メモリの使い方や、使用しないフィールドデータ等に余分な要素が多いという問題もあります。

Advect Velocity、Divergence Free、Density Advectに関しては、並列/平行処理を行うためにGPUを使用するという方法があり、HoudiniのPyroSolver、SmokeSolverの「Use OpenCL」にチェックを入れることで、3つの処理をGPUで行えるように設定することができます。

また、Simulation Objectのデータに関しても、デフォルトではSOPでボリュームを作成し、それをGeometryDataに複製し、DOP内で再構築してそれを使用するため、SOP側のデータの持つ情報が多ければ多いほど、DOP内に持ち込むための複製に時間がかかってしまいます。そのような場合は、使用頻度の低い情報を一時的なFieldで代用することで、メモリの使用量の削減が行えます。

 

次に、実際に制作の現場でどのようにHoudiniのVolumeSolverを運用しているかという事例について、ご紹介頂きました。実際にHoudiniのシミュレーションを行っていく中で発生した「シミュレーションの結果が返ってくるのが遅い」「レンダリングのルックの向上にもっと時間を割きたい」「属人的で、クオリティやかかる時間に差が出すぎている」といった問題点を、運用によってより効率よく作業ができるようにできないかということで、Solverのマネジメントを始めたとのことでした。

既存のSmokeSolverおよびPyroSolverに関しては、「アーティストによるForceの追加、編集、またはパラメータの調整が必要になる」「アニメーションの調整が難しい」「汎用的に作られているのでメモリ使用量が多い」「若手の学習が進まない」といった問題点がありました。

そのため、カスタマイズした「Alien Solver」を作成し、そちらでシミュレーションを行うようにワークフローを変更しました。OpenCLが使用可能で、Advectionに注力できるようにし、メモリ使用量を比較的削減し、流れをつかみやすいシンプルなネットワークにすることをコンセプトとして作成されたとのことです。

ベースはあまり変更していないため、デフォルトのPyro もしくはSmoke Solverと比較しても見た目の変化が少ないです。

パラメータにも手を加え、便利な設定やOpenCLへの切り替え等も、少ない操作で行えるように設定しています。また、Dispersionの設定、サブステップの設定の簡略化、その他実際に使用するパラメータを操作しやすく、一つのUIにまとめられています。ネットワークも、Houdiniの基本の流れと同じになるように設定しました。追加、編集が難しいExtra Forceに関しても、専用のノードを作成し、どの要素が必要なのかという判断を補助し、より素早く作業できるようにしています。また、中身は公開していたため、シニアのアーティストからのフィードバックをもらい、改善することもできたとのことです。

さらに、実際にこのカスタマイズしたシミュレーションワークフローを使用する場合は、プロジェクト毎に、どういったものが必要かを確認し、使用するノードやField、表現するエフェクトの内容、キャッシュに書き出す情報、OpenCLの使用を行うかどうか等を、確定するようにしているとのことです。これにより、作業をした人によってデータの重さや作業の早さ、見た目が異なるといった状況を回避することができます。

その後、表現したいSimulation Modelに対して、どのようなデータやノードを接続するかの例をご紹介頂きました。火、蒸気のような煙、重たい煙等、各エフェクトに合わせて使用するFieldやExtra Forceを明確に指定することで、キャッシュの最適化と、ノードを用意してつなぐだけで最低限の用意ができ、アーティスティックな作業に注力できるようになりました。

計算時間に関しては、Pyro、Smoke Solverに比べ、DOPネットワーク全体の処理時間を1分程、Solver単位で見ても20~40秒程短縮することが可能となりました。この差は、高解像度またはフレームレンジが長い程有利に働くと考えられます。そのため、コストの高いマシンでのパフォーマンスの向上よりも、まずSolverのワークフローをマネジメントする方が、比較的ローコストで処理速度が向上する可能性があるとのことでした。以下の画像は、カスタマイズしたVolumeSimulationを使用して作成したエフェクトの作例です。

 

その後は、実際にHoudini内で、カスタマイズしたAlien Solverのシミュレーションのワークフローをご紹介頂きました。上記設定の流れのデモと、実機でのPyro、Smoke Solverとの比較シミュレーションテストが行われました。

また、MicroSolverを使用したカスタムの乱流フィールドの作成例についてもファイルを開いてご紹介頂きました。Gas MatchField DOP を使用してDensityを元に「potential」という名前でベクターのテンポラリFieldを作成し、GasFieldWrangleDOPで「potential」Fieldを上書きし、データを追加します。どのように働くかも設定する必要があるため、Gas Calculate DOPを追加し、VelocityFieldに作用するように設定します。それをSolverへ追加することで、カスタムの乱流フィールドによって煙にノイズを追加することができます。

カスタムの乱流フィールドによってのみノイズを追加することもできますが、ソースのノイズも重ねて適用することもできます。

前半のスライドでもご紹介頂きましたDivergenceについても、Houdini のDOP内で実際に設定し、表示しながらご説明頂きました。PyroSolverの設定でもDivergenceを作用させることは可能ですが、Wrangle等を使用してDivergenceに値を直接定義することで、VectorのFieldとGradientを使用して設定するより簡単に、煙に対して縮小もしくは拡大させる圧力のようなものを追加することができます。

最後の質疑応答の時間では、学習方法や、今後のDOPの最適化の方針についてなど、様々なご質問がありました。