>   >  LiNDAのHoudiniBros.チームが総力戦で挑んだ荒海ショット/No.2 海エフェクト篇
LiNDAのHoudiniBros.チームが総力戦で挑んだ荒海ショット/No.2 海エフェクト篇

LiNDAのHoudiniBros.チームが総力戦で挑んだ荒海ショット/No.2 海エフェクト篇

出港後に荒海を進むシーンではGuided Ocean Layerを使用

▲Guided Ocean Layerは、波の表面(赤色部分)だけにFLIPシミュレーションを適用する手法で、波の中(緑色部分)に含まれるパーティクルのVelocityを更新後にReseed(密度の少ないところにパーティクルを作成)するか、パーティクルをSink(削除)することで、ガイドとなる海面のメッシュに沿わせている


本手法は海面のメッシュ形状をある程度維持したままFLIPを適用したい場合に有効なので、演出された波の動きにFLIPを合わせる必要があるショットで使用している。ただし、波があまりに速すぎたり、大きすぎたりすると意図しない動きになるため、その対策としてマイクロソルバを開発した。

▲例えば、【左】ではGas SDF Forceを適用している。【右】は適用せずに重力をかけた場合。Gas SDF Forceは、ガイドとなるフィールドの法線方向に重力をかけるマイクロソルバで、距離に応じて重力のかかり具合を調整できる。飛沫部分やコリジョン周辺にはForceが影響しないようにすることも可能。海の推進力が足りず、重力によって海面が滑り落ちてしまうことを回避する目的で開発した。なお、Guided Ocean Layerの使用時には効率化のために分散シミュレーションを行なっている。1台で計算した場合には約12時間かかる計算が、4台に分散すると約3時間まで短縮できたので、より多くの時間をクオリティアップに使うことができた

FLIPシミュレーションの負荷を減らしつつ、リアルな荒海を表現

前述したように、前半の港近くのシーンはWave TankのNarrow Bandを使用している。Narrow Bandを使うと、海面はパーティクル、海中はボリュームを使ってFLIPシミュレーションをすることで、データ量や計算負荷を減らしつつ、リアルなルックを表現できた。そのため、ある程度の深さがある波打ち際や、砕波(沖合いから水深の浅い海域に侵入した波が、前方へ崩れる現象)がほしいシーンにおいて有効だった。

当初は分散シミュレーションを使う予定だったが、4つに分割(Slicing)したデータをDeadlineで回してみたところ、Slicingされたジョブ間での通信が上手く行われず、シミュレーションが進まなくなるケースがあった。なお、Houdini 17.5からはNarrow Bandも分散シミュレーションに対応したとのことなので、最新のHoudiniを使えば同様の問題は発生しないと思われる。「メモリは64GBだと途中で落ちるショットもありましたが、128GBであればおおむね問題なかったです。ただしレンダリングに2日近くを要したショットや、128GBでも落ちたショットもあり、本作を超える規模のシミュレーションは現実的ではないと感じました」(北村氏)。

FLIPシミュレーションとOpen Oceanをマスクでなじませる

▲前述のコンテナエリアでは、Ocean Spectrumの情報をOcean Sourceでパーティクルとボリュームにした後、FLIPシミュレーションを適用している。このコンテナエリアと、周辺のOpen Oceanの境界をなじませる際には、Particle Fluid Maskを使用。主要なマスクは【左】Boundary Mask(境界用のマスク)と【右】Inner Mask(SpectrumのディテールをFLIP上に乗せるためのマスク)の2種類で、マスク部分にはSpectrum(Open Ocean)のメッシュ形状がオーバーライドされる。マスクのRGBの値は(1, 0.5, 0)となっている。2種類のマスクは、コンテナに入っているSpectrumの数だけ必要となる


▲Boundary Maskは、デフォルトだと【左】のようにXY方向に均等に適用されるため、【右】のように不均等に適用できるよう改良することで、画面手前の港の埠頭に近い領域までOpen Oceanになってしまうことを回避している


▲VDB Combineなど、VDB(ボリューム)に何らか処理を加えた場合には、【左】のようにマスクの端に乱れが生じることがあったため、【右】のように修復する処理を追加することもあった

パーティクルとボリュームも、計算負荷を抑えつつメッシュ化

FLIPシミュレーションを適用したパーティクルとボリュームは、Particle Fluid SurfaceとOcean Evaluateを使ってメッシュ化している。メッシュ化の対象範囲が広く、ディテールの情報量が多いため、特に計算負荷の高い工程となった。そこでDropletなどの飛沫のパーティクルに、ぎりぎりメッシュが貼られるくらいの精度に留め、ポスト処理で部分的に解像度を上げるフローを採用した。

▲【上】のパーティクルにメッシュを貼って【中】を作成。ガタガタしている部分にはスムージングをかける必要があるものの、飛沫の解像度が低いため、小さくなりすぎることがあった。そのため、【下】のように海面と飛沫とでウエイトを変えられるようにした。赤色の部分はウエイトが弱く、青色の部分はウエイトが強い


▲メッシュ化直後の飛沫【左上】はすごくポリポリしているため、Connectivityで全体をざっくり分離【右上】し、Measureで体積を計り、飛沫と海面を分離【左下】し、飛沫にのみ後述する処理を適用した。飛沫は、体積情報を基に、小さいものほど少しだけ膨らませ、SubdivideをかけてVDBにしている。VDB Smoothを少し適用し、Convert VDBでポリゴン化すると、かなり見た目がよくなる。【右下】では飛沫だけ解像度が上がっている

©Nintendo・Creatures・GAME FREAK・TV Tokyo・ShoPro・JR Kikaku ©Pokémon
©2019 ピカチュウプロジェクト


次ページ:
FLIPシミュレーションとOpen Oceanの境界処理

特集