チュートリアル / Bifrostはじめました
第6回:シーンの最適化と高速化
- Maya
- コラム
- シミュレーション
- チュートリアル
- 中級者
- 学生・初心者
最適化や高速化
前回の記事の最後に次はガイドシミュレーションを解説しましょうと書いておりましたが、このまま突き進んでしまうと計算コストが非常にかかってしまい、コーヒータイムが増えてしまいますよね。そこで少し最適化に関するパラメータに時間を割きたいと思いますのでお付き合いください。ちなみに目標としては次回のコラムまでにこんなシーンを作っていきたいと思っています。
Bifrostの動画でよくあるシーンですね。いろんな作り方があるんですが、私の場合はモーションフィールドで作成しました。意外と計算負荷がかかるので少しずつ説明していきます。シーンはこちらからダウンロードできますので、ご自由にお試しください。
マスターボクセルに関して
マスターボクセルはBifrostでの計算の単位になってくるので、基本のパラメータです。この連載の中でも何度も出てきています。効果の違いが分かるように下記のシンプルなシーンを使って説明します。
トレイに上から水が落ちてくるという設定です。ただスケールを考えずに作ってしまったので10m四方のトレイに大量の水が落ち来るようなシーンになってしまいました。このスケールの問題も後で修正の仕方を解説したいと思います。
ではこのシーンですが、初期状態ではマスターボクセルは0.5になっています。
連載の第3回で書いたようにBifrostではMayaのプリファレンスで設定されたユニットの値をベースにして単位が決まります。作業単位をセンチメートルに設定している場合、1グリッドが1mになります。
単位の話は後程詳しくしますが、基本的にこのマスターボクセルの値を小さくするほど計算精度は上がっていきます。
マスターボクセルの数値を0.5 , 0.25 , 0.125 , 0.0625と変化させてみました。下記で違いをご覧ください。
一目瞭然ですね。パラメータを1/2ずつに変更していますが、小さな数字にすればするほど精度があがり、より良い結果が出ているのがわかります。では小さいパラメータにすれば良いじゃないかということになりそうですが、そういうわけにもいけません。マスターボクセルの値は長さの単位なので、例えば値を半分にするとサンプル数は2*2*2で8倍になります。
0.5と0.0625では長さは1/8ですが、サンプル数の違いは単純計算では8*8*8で512倍になります。
といわけで、闇雲にサンプル数を上げても3乗でかかってきますので計算負荷はなるべく抑えるようにしていきましょう。
サーフェイスに資源を集中する
Bifrostではボクセル単位で計算を行っていたわけですが、実際に人の目に映るのはサーフェイス化された部分のみです。その部分のサンプル値をあげれば計算コストを抑えてより良い結果を得ることができます。下記をご覧ください。
左がサーフェイスのサンプルを増やしたもの、右はデフォルトのままのものです。サーフェイスからどの深さまでサンプルを増やすかのパラメータも調整できるようになっています。
具体的にはbifrostLiquidPropertyContainer内の放出>パーティクル配分のサーフェスパーティクル密度のパラメータです。ちなみにこのパラメータも3乗で効いてきますのでご注意ください。
サーフェイス帯域がサーフェイスからの距離です。シーンによりますが、この値を大きくしてしまうと流体内部までサンプル値が上がってしまいますので、ご注意ください。実際に値を入れて計算結果を見てみましょう。
左がサーフェスパーティクルの密度を高めたもの、右はそのままのものです。結果が異なっているのがわかると思います。
隙間?
さて、次の項目に。と言いたいところですが、もう少し調整していきましょう。このシーンを見ると実は隙間が空いています。
これはコリジョンの設定が甘いためです。流体の発生源としては隙間をきっちり埋めているのですが、実際のところは空いてしまっています。
ではパラメータを調整していきましょう。
設定項目はColliderPropsの変換です。
厚みの単位はVoxelでもWorld Unitでも構いませんが、Voxelの場合はマスターボクセルの値と積になりますので、マスターボクセルの値は確認しておいてください。
むやみにボクセルスケールを小さくするとコリジョンオブジェクトの判定サンプルの値が大きくなってしまいますので、ご注意ください。デフォルトの1だとマスターボクセルの値でサンプルするという事です。
厚みを0にすれば一見よさそうに思えますが、実はそうではありません。試しに0にしてみました。
このようにコリジョンオブジェクトの中にパーティクルが溢れてしまいました。(見えやすいようにパーティクルのサイズを大きくしています)
これはコリジョンオブジェクトに対してボクセルサイズの方が大きいため起きてしまった現象です。
そこでシーンの大きさに合わせてパラメータを調整してください。スケールの大きさの調整はマスターボクセルの値の積になること、その値は減らした値の割合の3乗になることを注意してください。パラメータを調整すると下記のようになります。
ドライブするオブジェクトを設定する
ここまで書いておいてなんですが、今回の内容は地味ですね。そこでアニメーションをドライブするためのものを作っていきましょう。
今回の波は前述したようにモーションフィールドを使用して作成しました。その元になったアニメーションはBOSSで作成しています。
では、これからBOSSの設定に入っていきましょう。
BOSSは缶コーヒーではなく、Bifrost Ocean Simulation Systemの略です。海洋のような広域を計算すると、とてつもなく計算リソースが必要となります。そこでBOSSを使ってディテイルが必要ない部分はカバーし、近接部分などはBifrostで計算すれば良いわけです。BOSSではどのようなメッシュに対して効果をかけてもいいのですが、今回はビーチのドライブに使いたいので、グリッドに対して実行します。
では実際に使用してみる
ポリゴンプリミティブからPlaneを取り出してください。BOSSもBifrostと同様Mayaが1ユニット1センチメートルの設定をしているときには1ユニット1メートルで計算を行っています。ビーチを表現したいのである程度の大きさに設定します。
今回大きさを20ユニット=20メートル、解像度を100*100で設定しました。
BOSS>BOSSエディターを選択します。
BOSSエディターが開きますので、Planeを選択した状態でBOSSソルバーのSpectralWaveをクリックします。
これでPlaneがBOSSの効果を得ることになりました。
再生すると下記のようになるはずです。
一見よさそうですが、まだ少し調整が必要です。
現在は波の動きは垂直方向で、水平方向の動きがあまり取られていません。
そこでBossSpectralWaveのアトリビュート上で水平方向のディスプレイスメントを使用にチェックを入れ、現在波のサイズが0.5になっていると思いますので、適切な値を入れてください。私の場合は4を入れておきました。ついでに波の大きさのパラメータを使うと現在の波の高さに係数をかけることができますので、適当な値を入力してください。
折角なのでもう少しディテイルを上げていきましょう。現在BOSSがかかっているPlaneの解像度は100*100です。これでは解像度が足りません。そこでPlaneを選択し、解像度を200*200に変更してください。重くなるのではないかと思いますが、それは後から解説します。次により細かいディテイルを追加するためにBOSS Editorを再度選択し、追加でSpectralWaveを設定してください。二つのWaveが追加されることでより詳細な表現が得られていると思います。
Alembicキャッシュを利用する
いい感じの表現が得られましたが、このままだとBOSSにCPUパワーを取られてしまい、Bifrostをかけるときにより多くのコンピューティングパワーが必要となってしまいます。また、ダイナミックス系はどれもそうですが、計算が複数重なると予期せぬ結果が出てきてしまうため、確定した動きに関してはキャッシュを取ってしまうのが安全です。
キャッシュは色々な方法がありますが、今回はAlembicを使用してみましょう。
やり方は非常に単純です。対象になるオブジェクトを選択し、キャッシュ>Alembicキャッシュ>選択項目をAlembicに書き出しのプロセスでAlembicキャッシュにすることができます。
Alembic化しているので、もうBOSSのほうは必要ありません。New Sceneでも構いませんし、消去でも構いません。PlaneやBOSSはない状態にしてください。メモリーは使用しますが、CPUの負荷は減少していますので、リアルタイムで動作させることができるようになります。
では次回はこのAlembicを利用してBifrostをドライブする手法をご紹介します。その過程で別の最適化手法に関しても紹介していく予定です。