今年5月21日に公開された『Island - Houdini Environment』(vimeo.com/420999972)。Spade&Co.にてCGディレクターとして活躍する木川裕太氏が自主制作したものである。そのクオリティの高さから海外のCG系メディアでも紹介されたが、今回は木川氏自身に一連の制作過程について、Houdiniワークを中心に解説してもらった。

※本記事は月刊「CGWORLD + digital video」vol. 268(2020年12月号)からの転載となります。

TEXT_木川裕太(Spade&Co.)
EDIT_沼倉有人 / Arihito Numakura(CGWORLD)、山田桃子 / Momoko Yamada

  • Spade&Co.
    映画やCMを中心としたCG・VFX制作を行うプロダクション。
    Sspade-co.jp

大規模エンバイロンメントワークに欠かせないツールとなったHoudini

現在、筆者はSpade&Co(. スペード・アンド・カンパニー)のCGディレクターとして映画やCMのVFX制作に携わっています。ゼネラリストやマットペインターとしての経験を活かし、2Dと3Dを組み合わせたエンバイロンメントワークを得意としています。

  • 木川裕太/Yuta Kigawa
    CM制作におけるゼネラリスト、マットペインターを経て、現在はCGディレクターとして映画案件を中心にVFX制作に携わる。主な参加作品は『るろうに剣心』シリーズ、『キングダム』、『マスカレードホテル』など。
    @ykigawa artstation.com/ykigawa

邦画のVFXにおいては、求められるクオリティや物量が年々高まっています。特にエンバイロンメントに関しては同じシチュエーションでも様々なカメラワークやライティングに対応できるよう、従来の2.5Dマットペイントではなく完全な3D環境での制作が求められることが多くなりました。しかし、3Dエンバイロンメントは往々にしてシーン内の物量が多くなり、マクロ・ミクロ視点でのコントロールがしづらくなりがちです。そうした中、Houdiniを活用すると大量のアセットを効率良く処理し、柔軟にコントロールするしくみを構築することが可能となります。

そこで今回は、個人的に制作した『Island』を例に、HoudiniとArnoldを使って大規模な自然景観を制作する手法をご紹介します。この作品は4日間、本業の仕事が終ってからの数時間を使って制作し、アイドル時のPCでレンダリングしました。自然景観はアセット数も多く、制作時間がかかりがちですが、ポイントを押さえて見える箇所に注力し、Houdiniによるプロシージャルなワークフローを活かすことで、短時間でも説得力のある画を作成できるということを今回お伝えできれば幸いです。

なお、効率良く制作するためには、プロシージャルに構築する部分とそうでない部分を上手く切り分けることが重要です。Houdiniを使用していると、どうしてもプロシージャルなしくみを構築することを意識しがちですが、エンバイロンメントワークにおいては、必ずしも全ての箇所をプロシージャルに構築する必要はありません。本記事では、その切り分けのヒントになる内容もいくつかお伝えします。

<1>現実のモデルをリファレンスにリアルな地形をつくる

Height Field関連機能とポスト処理で地形を仕上げる

地形のモデリング工程は大きく分けて2段階あります。まずはHeight Fieldでのベース制作、次にポリゴン変換後のポスト処理です。Height Fieldでねらった形状を作れるようになるには、ノイズの組み合わせ方やノードの応用的な使い方など、様々なテクニックが必要になってきます。また、Height Field関連のノードはたくさんあるので、初めて使う人にとっては多少とっつきにくいかもしれません。これから使い始める人はインターネットにあるチュートリアルから、様々な人たちのテクニックを学ぶことをオススメします。

なお、今回のようにバリエーションの必要がないユニークな地形を制作する際は、プロシージャルなしくみは意識せずつくっていく方が効率的です。

DEMをベースにHeight Fieldでベースを制作

今回は資料集めの段階でイメージにピッタリな島を見つけたので、その島のDEMをベースに進めます。広大な地形は感覚的に作業するとスケール感が狂いやすいので、実在しない地形をつくる場合でも、近しいスケール感の地形からDEMを取得してリファレンスにしています。DEMをインポート後、Height Fieldの機能でシルエットやディテールを整えます

▲DEMはWebサイト「terrain.party」からダウンロード



  • ▲Height Field FileでDEMをインポート



  • ▲そのままでは荒いのでHeightField Blurで均します

▲DEMから取得したラフな形状を整えるため、HeightField Noiseで大中小複数のノイズを作成



  • ▲作成したノイズを重ねる前



  • ▲ノイズをHeightField Layerで重ねた後

▲地形全体にノイズを重ねてしまうとCGくさい単調な地形になってしまいがちです。そうならないよう、部分的にマスクしながら複数のノイズを重ねます

尖りと浸食の効果を加える

印象的でリアルな地形にするため、Height Fieldの機能を使って尖りと浸食効果を加えます。浸食効果を得られるHeighField Erodeはリアルな地形をつくる上で欠かせない工程です。重たい処理になるので事前にHeightField Cropで不要な部分をクロップして計算から除外しておきます。また、解像度が不足していると侵食が綺麗にかからないので、必要に応じてHeightField Resampleで解像度を上げておきます。なお、HeightField Erodeで自動生成される各種フィールド(sedimentやdebrisなど)は後の工程でも使用します



  • ▲調整前の状態



  • ▲HeightField Mask by FeatureやHeightField Draw Maskで上側をマスク

▲HeightField Remapで形状を上に引き伸ばしたところ



  • ▲HeighField Erodeで浸食効果を加えた様子



  • ▲Erodeで生成される各種フィールド



  • ▲尖り処理のノード構成



  • ▲Erodeのノード構成

ポリゴン変換とポスト処理

まずはConvert HeightFieldでポリゴンに変換してからRemeshで均一なポリゴンにしておきます 。変換後はVOPでディスプレイスメントを加えて完成させます。現実の地形では、傾斜が緩い箇所は草木が生えたり堆積物が溜まったりして岩盤が覆われていることが多いです。そのため、岩肌のディスプレイスメントは傾斜の大きい面に対してのみかけると、よりリアルな地形になります



  • ▲ConvertHeightFieldでポリゴンに変換した結果。ポリゴンが縦長に伸びてしまっている



  • ▲Remeshで均一なポリゴンに

▲Attribute VOPでNormalのY情報だけ取り出して、岩盤部分のマスク用アトリビュートを作成

▲Heightマップテクスチャやプロシージャルノイズを組み合わせてディスプレイスメントを加えます。その際に【岩盤部分のマスク用アトリビュート】を使って岩盤部分のみディスプレイスメントがかかるようにします

▲同様に奥の山、ビーチ、海底、離島なども作成して地形モデルは完成です

次ページ:
<2>こだわる部分と大ざっぱな部分を切り分けて効率良くシェーディングする

[[SplitPage]]

<2>こだわる部分と大ざっぱな部分を切り分けて効率良くシェーディングする

シェーディングの出来で見た目の大部分は決まる

ここからは、作成した地形メッシュにシェーディングをしていきます。地形の形状がいくらリアルにできてもシェーディングが悪いだけで一気にCくさくなってしまいます。逆に言うと多少地形メッシュがイマイチだとしてもシェーディングである程度カバーすることができるので、この工程はとても重要です。

地形制作とはちがい、ここからの工程はプロシージャルなしくみを意識してつくっていきます。プロシージャルなしくみを構築することで、一度つくってしまえば地形メッシュに変更があった場合も柔軟に対応することができるのと、他プロジェクトでのアセット流用がしやすくなります。特に自然景観はシェーディングをした後に形状修正に戻る、といったこともザラなので、多少手間がかかってもプロシージャルを意識して作業しましょう。

手順としては、「1.各種マスク用のポイントアトリビュートを作成」、「2.それぞれの質感(岩盤、砂浜など)ごとにマテリアルを作成」、「3.1の工程で作成したマスクアトリビュートを使ってマテリアルをブレンド」と なります。

各種マテリアル制作のながれは、まずは種類ごとに個別にマテリアルを作成しルックデヴをしていきます。今回のような広大な地形のテクスチャリングは、UVに合わせたテクスチャを用意するよりもタイリングテクスチャを用いてTriplanarでマッピングするのが効率的です。TriplanarでマッピングすることでUVにも依存せず、プロシージャルなアセットを組むことができます。草と砂浜のテクスチャはMegascansを利用しました。

一方、海底のマテリアルだけはUVマッピングでテクスチャを割り当てています。テクスチャは衛星写真をPhotoshopで加工したものを使ってパッチワークでつくりました。今回のカメラワークを考慮すると海を通して見たときにそこまでしっかり見えてくる部分ではなかったので、形状に合わせて描いたりはせず大ざっぱにつくっています。このように、こだわる部分と大ざっぱで済ませる部分のメリハリをつけることが、エンバイロンメントワークに限らず、作業効率アップのために重要です。

最後の工程として、Layer Shaderを使い、各マテリアルをブレンドします。[mix]には各種マスクアトリビュートを接続しますが、これらはプロシージャルに組まれているので、地形の形状や位置が変わったとしてもシェーディングの見た目はキープされます。

各マテリアル適用箇所を分けるためのマスク作成

今回作成したマスクの一例です



  • ▲海底部分のマスク



  • ▲砂浜部分のマスク



  • ▲岩盤部分のマスク



  • ▲岩盤部分の汚しマスク

▲各種マスクのノード構成。Attribute VOPを使用して作成しました。海底と砂浜部分のマスクはPositionのY情報を使用して作成しています。また、岩盤部分のマスクは前ページでディスプレイスメント処理用に作成した岩盤アトリビュートを流用しています

▲Position情報を使用したグラデーションマスクを作成する際、リニアなグラデーションになってしまうとCGぽさが際立ってしまうので、なるべくノイズなどを組み合わせてマスクの境界部分が複雑になるようにします

草マテリアルはランダムカラーアトリビュートを混ぜてタイリング感を消す

Megascansからダウンロードしてきた草のタイリングマテリアルをTriplanarでマッピングします。ただマッピングするだけでは色味が単調でタイリング感が目立ってしまうので、事前にランダムな色情報をもったポイントアトリビュートを作成、そのアトリビュートをシェーダ側で読み込んでMegascansのテクスチャとミックスさせています。これによって色の情報量が増え、CGっぽさを抑えることができます

▲草のマテリアルネットワーク



  • ▲レンダリング画像



  • ▲ランダムカラーアトリビュート

▲Triplanarの[Cell]を有効にすると、よりタイリング感が目立たなくなります

砂浜マテリアルは単調に見せないよう濡れた部分を表現

草と同様に砂浜もMegascansからダウンロードしてきたタイリングテクスチャを使用しました。特に砂浜の場合、カメラが引いてしまうとディテールがほとんど見えず単調になりがちです。実際の砂浜の写真を見ても単調ではあるのですが、ここではなるべく情報量を増やしたいので、水に濡れて色が暗く落ちているような印象を加えています。水に濡れた部分のマスクは前ページの通りPositionのY情報から作成しています

▲砂浜のマテリアルネットワーク

▲レンダリング画像



  • ▲水に濡れた部分のマスク



  • ▲汚しマスク

海底マテリアルは大ざっぱに作成

海底は、今回のカメラワークではしっかり見えてくる部分ではないので、大ざっぱに済ませます。テクスチャは衛星写真をPhotoshopで加工、パッチワークして作成しました。最後にLayer Shaderで各マテリアルをブレンドし、必要に応じてディスプレイスメントなども入れてシェーディングは完成です

▲海底のマテリアルネットワーク

▲Photoshopで加工しパッチワークしたテクスチャ画像



  • ▲海底マテリアルの適用結果



  • ▲【左の画像】に海面を合成した状態

▲Layer Shaderを使った各マテリアルのブレンド。[mix]に各種マスクアトリビュートを接続しています

次ページ:
<3>外部ツールSpeedTreeとHyperGrassで効率的に樹木と草木を作成

[[SplitPage]]

<3>外部ツールSpeedTreeとHyperGrassで効率的に樹木と草木を作成

植物アセットはコピペ感とポリゴン数に注意

今回、植物のアセットの作成にはIDV社のSpeedTreeを使用して、メインとなるヤシの木と低木、その他5種類ほどを用意しました。それぞれ樹木ごとに3~4パターン、ヤシの木は7パターンのバリエーションを用意しています。樹木の種類やバリエーション数は作成する地形やカメラアングルによって変わるので一概には言えませんが、今回のような場合はこのくらいあれば十分かと思います。

樹木を作成するポイントとして、大量に複製して使う都合上、特徴的な形はコピペ感がバレる原因となるのでなるべく避けるようにします。ただし、特徴的な形を省きすぎると画面が単調になってしまうので、要所で特徴的な形の木を入れ込むことも必要です。また、樹木のポリゴン数は多くなりがちです。レンダリングの負荷を下げるため、なるべく見えない部分のポリゴンは削るなど最適化を行いましょう。今回はだいたい1本5~50万ポリゴン内に調整しています。

SpeedTreeで樹木をモデリング

樹木はSpeedTree Libraryにあるモデルをベースに作成していきます。Libraryモデルはポリゴン数が多いので、TwigsやWeldingなどの引きで見えなくなるようなジオメトリは非表示にしておき、Segmentも必要最低限に落としておきます

▲SpeedTreeの作業画面

▲引きで見えなくなる枝を非表示にした状態

▲片側に偏って いるような特徴的な樹木(右)はインスタンスで複数配置した際に目立ちやすいのでなるべく避けます

▲アクセントとして用意した、少し折れ曲がったような特徴的なヤシの木。コピペ感が目立たない程度にポイントで配置しておくとリアリティが増します

▲今回作成した樹木27本

樹木のルックデヴで広範囲にわたる色ムラを発生させる

樹木のマテリアルはジオメトリと同一階層内にmatnetを作成し、その中で作業します。そうしておくことで、大元のジオメトリノードをコピーすれば他プロジェクトでもアセットをすぐに流用することができるので便利です

▲Geometryと同じ階層にmatnetを作成

▲matnet内のマテリアルネットワークの一部。Color Jitterを使って樹木ごとに多少色味が変わるようにしています。さらにスキャタリングの工程で作成するカラーノイズアトリビュートをbasecolorとミックスさせることで、Color Jitterだけでは表現できないような複雑な色のバリエーションを作成しています

▲ColorJitterとカラーノイズアトリビュートをミックスさせたサンプル。オブジェクト固有の色味の差(Color Jitter)を出しつつ、さらに広い範囲での色ムラを表現しています。大量のインスタンスを配置する樹木は色のバリエーションがあるかないかで画の中の情報量が変わってくるので、こういった色のランダム化はとても重要です

▲草はVertex Library社のHyperGrassのモデルを加工。サークル上にパッチ化された草モデルを密度と大きさちがいで6種類用意しています。草は樹木に比べインスタンス数が多くなるので、今回のようなロングショットの場合はパッチ化した状態にしてインスタンス数を減らすのが効率的です

<4>最終的なリアリティを大きく左右する植物アセットのスキャタリング

現実のエコシステムを参考にインスタンスを配置

今作で一番の肝になるのが、植物アセットを地形に対してスキャタリング(インスタンスで配置)する工程です。現実世界に存在する植物は何らかの要因に基づいて生え、成長しているため、一定の分布ルールが存在します。CGでスキャタリングする際も、このルール=エコシステムをどれだけ意識できるかが最終的なリアリティに大きく関わってきます。そのため、植物の分布がわかるようなリファレンスをたくさん集めてよく観察することが大切です。

今回の作例では、「ヤシの木は砂浜沿いに多く生え、中間から高所にかけては生えていない」、「その他の樹木は中間までは生い茂っており、高所にかけて徐々に減っていく」、「低木は低所から高所まで広く分布する」、「特定の樹木は一定箇所にまとまって生えている」という4つの分布ルールを意識して作業しました。

こうしたルールに従ってスキャタリングをコントロールするのは根気のいる作業です。ですが、適当にランダム配置したものと、エコシステムを意識して配置したものとではクオリティに大きな差が生まれるので、妥協せず丁寧に作業します。

具体的な作業手順を解説します。まずはノード構成として、【スキャタリングする際のノード構成】の画像のように3つのジオメトリを作成します。緑がマテリアル設定などの作業用ジオメトリ、青がインスタンスのソースジオメトリ、赤がInstance Object(実際にレンダリングされるオブジェクト)です。Arnold for Houdini(HtoA)では配置先のポイントアトリビュートをシェーダ側で読み込むにはInstance Objectを使用する必要があります。作業用ジオメトリではオブジェクトの読み込み、マテリアルの作成・アサインを行い、SpeedTreeでつくられる不要なグループやアトリビュートの事前削除も行います。

スキャタリング用のポイントはInstance Object内でつくります。まずは地形メッシュに対してAttribute VOPを接続し、densityアトリビュートを作成。リファレンスを観察しながら植物ごとの分布ルールに基づいたdensityアトリビュートを作成していきます。植物はパッチ感(かたまって生えている感じ)を意識してdensityを設定すると、リアルな分布になりやすいです。また、前ページの樹木ルックデヴで使用した、樹木の色味にバリエーションを出すためのカラーノイズアトリビュートをここで作成します。

作成したdensityアトリビュートを基にScatter SOPでポイントを発生させます。また、pscale、回転、instanceアトリビュートについてVEXpressionを記述し、各樹木のサイズや向きにバリエーションが出るように設定します。

なお、自作HDA(Houdini Digital Asset)でインスタンスの最適化も行なっています。

群生感を意識してdensityアトリビュートを作成

▲スキャタリングする際のノード構成。緑が作業用、青がインスタンスのソース、赤がInstance Object

▲作業用ジオメトリの中

▲Instance Object内で、地形メッシュに対しAttribute VOPを使いdensityアトリビュートを作

▲VOPのノード構成。Anti-Aliased NoiseやVoronoi Noiseを組み合わせてノイズを作成し、岩盤部分や海沿いには配置されないようPositionやNormal情報を使ってマスク。また、HeightField Erodeの工程で生成したsedimentやdebrisなどの堆積部分のアトリビュートでマスクすることで、さらに複雑な分布を作成できます



  • ▲パッチ感を意識したdensityアトリビュート



  • ▲densityに応じて樹木草木のインスタンスを配置した状態



  • ▲樹木の色ムラを表現するためのカラーノイズ



  • ▲Scatter SOPによる低木のScatterポイント

▲樹木AのScatterポイント

▲pscaleで大きさのバリエーションを設定。リニアな分布にならないように、powで小さい木が多くなるよう分布を調整し、densityも組み合わせて、密度が薄い部分ほど小さくなるようにしています

▲ランダムな回転を加えます。樹木は真上に向かって配置し、低木や草などは地形の法線に沿って配置されるようにします

▲instanceでインスタンスソースを指定します

自作のHDAでフラスタム外とカメラのオクルージョン箇所のポイントを削除

自然景観の場合、数百万~数千万のインスタンスを配置することになるため、カメラから見えない部分にはインスタンスが配置されないよう最適化することがオペレーション、レンダリングの観点から非常に重要となります。筆者は、複数フレームにわたって確実に見えない箇所(フラスタム外、カメラからのオクルージョン箇所)のポイントやプリミティブを削除する自前のHDAで最適化しています

▲HDAによるインスタンスの最適化結果

▲pscaleや回転、instanceの設定などは何度も行うことなので、作業効率を上げるためにもこれらの処理はHDA化することをオススメします

次ページ:
<5>特徴的な山のシルエットを強調する逆光気味のライティングで画づくり

[[SplitPage]]

<5>特徴的な山のシルエットを強調する逆光気味のライティングで画づくり

作業の前に画のイメージを固めるよう心がける

これまでの工程では個々のアセット制作やスキャタリングなどデータを作る作業が主でしたが、ここからはライティングやコンポジットなど最終的な見映えに関わる画づくりを行っていきます。同じ風景でも切り取る時間帯や天候、キーライトの位置がちがえば画面内の印象は大きく変わってきます。日中なのか夕景なのか、晴れているのか曇っているのか、画面内のどこを強調して見せたいのか。ただ闇雲にライティングをするのではなく、作業に着手する前にどういった方向性の画に落とし込んでいくのか、頭の中にしっかりとしたイメージを固められるようにリファレンスを集めて、事前に方向性を決めておきましょう。

今作ではメインとなる山のシルエットが特徴的だったので、シルエットがより強調されるように逆光気味にライティングしています。ただし逆光にしすぎると画面内が影に覆われて立体感がなくなってしまうので、トップめからの逆光にして、光が当たっている部分と影になっている部分のバランスが適切になるよう意識してライティングしました。

自然景観の画づくりにおいては、ライティングのみならず、霞、フォグ、雲(と雲の影)などの空気感の演出やカメラワークもスケール感を表現する上で大切です。現実をしっかりと観察し、集めたリファレンスを読み解いてリアルな表現を追求していきます。

陰陽バランスを考慮したライティング

▲HDRIをベースに、Distanceライトをキーライトにして別途コントロールしています



  • ▲光と陰のバランスを整えた採用バージョン



  • ▲順光すぎるライティング例

▲逆光すぎるライティング例。光と陰のバランスが悪いと立体感の乏しい画になってしまうのでなるべく避けます

雲の影などゴボ効果の活用でスケール感が出る

▲今作では行いませんでしたが、雲の影などのゴボ効果を入れることで、よりスケール感が出て画に立体感が生まれるのでオススメです

Volumeによる霞の表現

Volumeを使って霞を入れていきます。こういった霞はコンポジットで入れてしまうこともありますが、今回のような逆光の場合、3D的に表現した方が光の回り込み感がリアルに出るでしょう

▲霞を入れたい部分にBoxを配置し、Cloud SOPでボリューム化します

▲Standard Volumeの設定。Scatter Colorに若干青みを入れています。また、逆光感を強調するために[Anisotropy]を0.5に設定しています

▲霞の適用前

▲霞の適用後(どちらもコンポジット前)

レンズ効果を施してコンポジット

▲HDRI素材をCardにプロジェクションして空を作成。Cardは上にいくにつれカメラ側にくるよう変形し、カメラワークで多少パララックスが感じられるようにしておきます

▲レンズ効果として、グローや色収差、レンズディストーション、グレインを入れていきます。レンズ効果は過剰に入れがちですが、実際のカメラやレンズで起こりうる範囲に留めておくことがリアルな画づくりにつながります

▲最近のシネマレンズでは広角レンズでもほとんど色収差は感じられなかったり、このくらい明るいシーンではノイズもそこまで乗ることはありません。そういった「実際のカメラやレンズだったらどうなるか」を意識しながらコンポジットします

まとめ

少し前までは、このような自然景観を3DCGでつくるのはコストが高くなりがちでした。ですが現在では、Houdiniがあれば短時間でも説得力のある画を生み出せるようになりました。しかも、今回作ったシェーダやスキャタリングのしくみはプロシージャルに組んでいます。もし別のプロジェクトで使いたいとなった場合にも、すぐに流用することができるのです。

特に自然景観では、地形から植物の分布まである程度決まったルールに基づいていることが多いです。そのため、一度Houdiniでつくったしくみをライブラリ化しておけば、限られた制作期間の中でもさらに効率良く制作できるはずです。また、複雑でテクニカルな工程をHDA(Houdini Digital Asset)化しておくことで、Houdiniに慣れていないアーティストでも感覚的に作業できます。これもHoudiniの大きな強みです。

筆者の所属しているSpade&Co.では現在、大作映画のVFXに関わっています。今回ご紹介したようなエンバイロンメントワークやエフェクトなどを日々Houdiniで制作しているので、ご興味がある方はぜひご連絡ください。



  • 月刊CGWORLD + digital video vol.268(2020年12月号)
    第1特集:百花繚乱! 最新ゲームグラフィックス
    第2特集:『モンスターストライク THE MOVIE ルシファー 絶望の夜明け』
    定価:1,540円(税込)
    判型:A4ワイド
    総ページ数:128
    発売日:2020年11月10日