グリオグルーヴ LiNDAのHoudiniBros.チームは、その名が示す通りHoudiniに特化した10人のスーパーバイザーやアーティストで構成されている。10月28日(木)公開のパイプライン篇では、そんな彼らが総力戦で挑んだ映画『ミュウツーの逆襲 EVOLUTION』のヘビーな荒海ショットにおけるHoudiniBros.のパイプラインを紹介した。以降の海エフェクト篇では、嵐によって荒れ狂う海のシーンにおける、海面のエフェクト制作について紹介する。

※本記事は月刊『CGWORLD + digital video』vol. 255(2019年11月号)掲載の「LiNDAのHoudiniBros.チームが総力戦で挑んだ荒海ショット」に加筆したものです。

TEXT_今宮和宏、北村祐也(グリオグルーヴ LiNDA HoudiniBros.チーム)、
尾形美幸 / Miyuki Ogata(CGWORLD)
PHOTO_弘田 充 / Mitsuru Hirota

  • 映画『ミュウツーの逆襲 EVOLUTION』

    2019年7月12日(金)公開
    原案:田尻 智/監督:湯山邦彦・榊原幹典/脚本:首藤剛志/エグゼクティブプロデューサー:岡本順哉・片上秀長/プロデューサー:下平聡士・關口彩香・長渕陽介/アニメーションプロデューサー:小林雅士/CGIスーパーバイザー:那須基仁/音響監督:三間雅文/音楽:宮崎慎二/アニメーション制作:OLM Digital/製作:ピカチュウプロジェクト/配給:東宝
    www.pokemon-movie.jp

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


▲LiNDAのHoudiniBros.チームが制作した、Houdiniによる荒海のデモムービー

近景の飛沫から遠景の海面まで、全域をメッシュ化

本作ではエフェクト制作にHoudini 16.5.405、レンダリングにArnold 5.0.1.5を使用している。海面の制作手法は大きく分けて2種類あり、前半の港近くのシーンはWave TankのNarrow Band、出港後にボートで荒海を進むシーンはGuided Ocean Layerを使用。いずれの場合も、FLIPシミュレーションの適用範囲外では、Open Oceanというメッシュベースの手法を使用した。従来であればOcean Spectrumの情報を基にメッシュにディスプレイスメントを適用するが、今回はMayaを経由してArnoldでレンダリングを行う必要があったため、海面の全域をメッシュ化した。飛沫や泡も近景から中景にかけては実際にパーティクルを発生させる手法をとっているため、多くのショットがヘビーな計算量となっている。Deadline(スケジューラ)に投げるジョブ(中間キャッシュ)は20〜30個となった。海面のベース形状作成から、ある程度のルック設定まではボタンひとつで自動的に作成され、プレビュー映像をレンダリングして確認できるしくみも構築された。

▲【左】Wave TankのNarrow Bandを使用した港近くのシーン/【右】Guided Ocean Layerを使用した出港後にボートで荒海を進むシーン

複数人での作業分担を前提に、柔軟に対応できるノードを構築

▲ベースとなるノードの全体像。図内の「3. Local Whitewater Mist」はFlIPシミュレーション用の飛沫・泡・微粒子のノード、「4. Global Whitewater Mist」はOpen Ocean用の飛沫・泡・微粒子のノード。デフォルトのノードを使用する場合もあったが、大半のノードは何らかの改良を加えている


▲例えばFLIPシミュレーション後のメッシュ化で使用したParticle Fluid Surfaceノードの場合、デフォルトの【左】は見づらいなどの問題があったため、【右】のように整理し、大幅な改良を加えた


▲海のメッシュ[Ocean]、飛沫や泡のパーティクル[Whitewater]などの各セクションを一括でコントロールするためのノード。本作ではひとつのショットを複数人で分担して仕上げており、ショット単位の調整も必要だったため、柔軟に対応できるノードが構築された


  • ◀▲ネットワーク内にある全てのキャッシュやレンダリングの設定もノードで管理できる。作業者が新たにキャッシュなどを作成することも想定し、ボタンひとつでリストを更新できるようになっている

海面のベース形状、コリジョン、FLIP用のコンテナを作成

▲【左】OLM Digitalから提供されたプリビズ。波の高さや速度感などが、メッシュの簡単なデフォームで表現されている。これを基に、Ocean Spectrumを使ってメッシュのベース形状を作成する。大きな起伏が必要なものは、Low、Mid、High、Customと、Spectrumを複数組み合わせ、ディテールを分けて作成。Cusp(白波が発生しそうな波の先端)に色を着けた【右】の状態で最初のチェックに出し、おおまかな見た目の承認を得る


▲SpectrumのTime Scaleの値を1以外に設定すると、後述するWhitewaterのFLIPシミュレーションも同じ値にしないと形状がずれてしまう。【左】左側はSpectrum、右側はFLIPで、値は共に1。RGBは高さ情報を表し、Rが最も高く、Bが最も低い/【中】値は左が2、右が1/【右】値は共に2


▲SpectrumのTimeScaleのテスト


海面のコリジョンは、ボートのような動くものと、港のような動かないものに分けて作成した。前者はシミュレーション時にサブステップ分が必要だったため、倍の尺にリタイムして取得したキャッシュを、元に戻した後にサブステップ分として使用した。

▲海面のコリジョン作成時には、VDBとVelocity情報をもったポイントを用意し、主にStatic Collisionを使用。FlipでStick on Collisionを使用するとき、Max Distanceの値がVDBのHalfwidth未満でないと影響範囲を上手く計算できないため、VDBはActivate SDFとし、最後にHalfwidthの値を調整している


▲コリジョンとカメラの情報を基に、FLIP用のコンテナを作成

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


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

[[SplitPage]]

出港後に荒海を進むシーンでは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の境界処理

[[SplitPage]]

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

▲前述のBoundary MaskとInner Maskを使い、Open Oceanのメッシュ形状をFLIPシミュレーションの形状にオーバーライドしてなじませている。【左上】Open Oceanのみ/【右上】画面中央はFLIP、周辺はOpen Ocean、黒色の部分は港の埠頭/【左下】FLIPとOpen Oceanの境界をBoundary Maskで平坦化したもの/【右下】FLIPとOpen Oceanの境界はBoundary Mask、境界以外の変化の少ない領域はInner Maskを使ってなじませたもの


海面のパーティクルはVDB from Particle Fluidを使ってメッシュ化したが、飛沫が波砕して複雑に入り組んだ形状になった場合に小さな穴が空くケースがあり、VDBがメッシュ化できずに消える現象が発生した。根本的な原因はわからなかったが、穴が空いたら埋める処理を加えることで対応した。なお、Whitewater Sourceに渡すデータも、海面のメッシュと同じく事前に境界処理を適用している。

▲飛沫などの小さなメッシュは透明度が高すぎるとスケール感が損なわれてしまうため、 CurvatureやSpeedを基にSSSを適用し、海面のシェーダとブレンドした。【上】SSSの適用前/【下】SSSを適用し、海面のシェーダにブレンドしたもの

飛沫や泡のボリューム感も考慮し、FLIPシミュレーションを調整

海面の飛沫(Spray)、海面の泡(Foam)、海中の泡(Bubble)の作成には、Whitewater Sourceを使用した。なお、以降で紹介する手法は、Houdini 17.0からはやり方が変わっている。Whitewater Sourceを使ったSource作成に加え、FLIPシミュレーション時にエラーとなったSourceポイント(ひとつだけ明後日の方向に飛んでいるパーティクなど)の削除も行なっている。ここでのSourceの量と、FLIP時のEmissionの量によってパーティクルが大量に発生したり、少なすぎたりする場合があったのに加え、Pscaleの値によっても見え方が変わるので、結果が予測しにくい工程だった。また、FLIP時の見え方よりもボリューム感が増すので、この工程まで進めないと最終的な見映えがわかりづらく、監督などのチェックでは注意が必要だった。

「Narrow Bandを使って飛沫の跳ね上がりを表現するショットでは、1回のFLIPシミュレーションでねらった形状の飛沫にするのが難しかったので、5パターンくらいのFLIPをまとめて実行し、プレビューを見てベストの結果を選んでいました。ただし、Whitewaterの工程で飛沫や泡が加わると、かなりボリューム感が増し、ひとまわりくらい印象が変わってしまうので、そこまで考慮してFLIPを調整しておく必要がありました」(今宮氏)。

▲FLIPシミュレーション時の海面


▲FLIPシミュレーションを適用した海面に、飛沫や泡(Whitewater)と微粒子(Mist)を追加したもの。ボリューム感がひとまわり大きくなり、キャラクターが波にさらわれそうになっている。「こういうショットでは、埠頭に跳ね上がる飛沫のベクトルを反転させて海面へ飛ばしたり、ポスト処理で波を低くしたりするなどして、ボリューム感を調整しました」(今宮氏)



▲飛沫や泡を調整した海面

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


次ページ:
飛沫や泡のシミュレーションも
対策を講じて負荷を軽減

[[SplitPage]]

飛沫や泡のシミュレーションも、対策を講じて負荷を軽減

Spray、Foam、Bubbleのシミュレーションには、Whitewater Solverを使用している。この処理も計算負荷が高いため、分散シミュレーションを行なった(FLIPとは異なり、お互いに通信しあう必要はない)。素早くルックを確認するため、海面のシミュレーションエリアから出たポイントや、カメラの範囲外にあるポイントを消したり、想定量の70%程度でシミュレーションを行なってから後処理でポイントを増やしたりといった対策を講じている。全ての要素をひとつのキャッシュにするとデータ量が膨大になり、入出力に負荷がかかり、ハンドリングが悪くなってしまうため、Deadline(スケジューラ)でキャッシュを分散することで入出力にかかる負担を軽減したりもしている。

FLIPシミュレーション用の飛沫や泡のポスト処理と、微粒子の表現

飛沫や泡(Whitewater)のポスト処理では、パーティクルの量やPscaleの調整、不必要なポイントの削除、カメラの範囲外のクリッピング、カメラからの距離に応じたLODなどを行なっている。1億個程度ならアンチエイリアスあり、Pscale込みの状態でビューポートやプレイブラストから確認できるため、1億個を上限にルックを作成した。

▲例えば【左】のパーティクルは400万個だが、【右】では3,600万個までポスト処理で増やしている。そのまま増やすと拡散して粉っぽくなり不自然なので、拡散したパーティクル同士を元のパーティクルに寄せ、筋が出やすいように調整する処理をしている


  • ◀▲【左上】のパーティクルを、【右上】では10倍に増やしており、【左下】では筋を出す処理を加えている


▲飛沫(Spray)よりも細かい微粒子(Mist)は、SprayのSpeedとAgeからSourceを作成し、Smoke Solverでシミュレーションを行なっている

Open Oceanは、メッシュベースのデフォームで作成

FLIPシミュレーションの適用範囲外の広大な海面(Open Ocean)は、Ocean SpectrumとOcean Evaluateを用いたメッシュベースのデフォームで作成した。

▲【左】カメラに映る範囲を全てカバーできるグリッドを作成し、距離に応じてRGB(Near, Mid, Far)のエリアに分ける/【右】カメラの範囲外をクリッピングし、FLIPのコンテナエリアをBooleanでくり抜く(FLIPを適用した海面メッシュがくり抜いた部分に入る)


▲【左】カメラに近いエリアほどSubdivideをかける/【右】RGBエリアの各境界でメッシュを分離するため、Opacity用のアトリビュートを追加してメッシュの重なりを防ぐ


  • ◀Spectrumを基に、Evaluateで海面の形状にデフォームさせ、Cuspに補助的な白波用のアトリビュートを追加して完成

Open Ocean用の飛沫、泡、微粒子の表現

Open Oceanの白波はパーティクルで表現しており、飛沫(Spray)と海面の泡(Foam)の2種類を用意した。いずれもOcean Foamを使わずに挙動をコントロールできるようにしている。

▲【左】FLIPシミュレーションとOpen Oceanをマージしたメッシュに加え、コリジョン用のボリュームも用意する/【右】わかりやすく色分けしたもの。緑色のCusp部分がSourceとなる


  • ◀生成されたSourceポイント


▲【左】Sprayと【右】Foamのシミュレーションは、POP Solverで行なっている。波のメッシュ形状に吸着させつつ、Cuspdir(波の先端方向へのVelocity)と、何種類かのノイズやForceで白波らしい挙動を作成した。シミュレーションの範囲が広大だったため、いくつかのクラスターに分割して計算している。また、カメラからの距離に応じてパーティクルの量を調整することでシミュレーション時の計算量を抑えている


  • ◀Open Ocean用の微粒子(Mist)の設定は、FLIPシミュレーション用のものに似ている。こちらの方が範囲が広いため、クラスターに分割して計算している

最終的に、108ショットのエフェクトを納品

2018年の7月頃から本格始動した荒海ショットの制作は、年内に全データの納品を終えた後、翌年の2月頃までブラッシュアップが続けられた。「荒海ショットがそろそろ終わるというタイミングで、『別のショットも手伝ってほしい』とOLM Digitalからお声がけいただき、炎、爆発、電撃などのエフェクトも手がけることになりました。電源も、サーバの容量も、マンパワーも限界まで使いきり、終わってみれば、108ショットのエフェクトを納品していました。次につながる貴重な経験ができたことを、とても嬉しく感じています」(桑原氏)。

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



info.

  • 月刊CGWORLD + digital video vol.255(2019年11月号)
    第1特集:僕たちがBlenderを使う理由
    第2特集:アニメCG×ゲームエンジン
    定価:1,540 円(税込)
    判型:A4ワイド
    総ページ数:128
    発売日:2019年10月10日
    cgworld.jp/magazine/cgw255.html