tpc-37

TOPIC37|PLATEAUでミニチュアルック映像を作る

このトピックでは、3DCGソフトウェアHoudini(フーディニ)を用いたミニチュアルック制作フローを紹介します。PLATEAUの3D都市モデル読み込み、テクスチャ設定、ディテールアップ、3Dスキャン合成、大規模シミュレーションまでを扱います。

PLATEAUの精細なモデルは、映像作品に使われることも多くなりました。このトピックでは、3DCGソフトウェアのHoudini(フーディニ)を用いた制作フローを紹介します。作例は、ミニチュアルックの3DCGです。PLATEAUの3D都市モデルの読み込みからはじまり、よりリアルに見せるためのテクスチャの設定、さらなるディテールアップ、そして3Dスキャンを用いた実物の3Dモデルとの合成、さらには、Houdiniを用いたスケールの大きいシミュレーションまでを扱います。

このトピックの内容は「PLATEAUでミニチュアルック映像を作る/3Dスキャンデータとの組み合わせと物理シミュレーション(2025年度PLATEAU Hands-on動画)」(2025年度PLATEAU Hands-onアーカイブ動画)でも制作方法をハンズオン形式で紹介しています。

【目次】

37.1   このトピックの見どころ

37.2   3D都市モデルを読み込んで基本的なシーンを作る

 37.2.1  3D都市モデルの読み込みと整理

 37.2.2  LOD1の建物にテクスチャを貼る

 37.2.3  Karmaでレンダリングする

37.3   ミニチュアルックの表現

 37.3.1  ミニチュアルックとは

 37.3.2  焦点距離の指定で表現する簡易な方法

37.4   ティルトシフトレンズを表現する方法

37.5   まとめ

37.1 _ このトピックの見どころ

本トピックで扱う題材は、広島を舞台とした全編フルCGのミニチュアルックアニメーションです。

ミニチュアのなかに登場した少年が、公園で魔法の杖を拾います。その杖を振るうと、建物からレモンが湧き出たり、もみじ饅頭が風で流されてきたりします。さらには、球場からコイが登場、そして、大きなお好み焼きが地面からせり上がってくるというように、広島の名産物が次々と登場します。

建築物モデルには、広島市の3D都市モデルを使用。ディテールアップのために、建物の屋上などには、既存のアセットを配置しています。広島市は緑が多いことから、町全体に木々も配置しています。

もみじ饅頭やお好み焼きなどの小物の3Dモデルは、LiDARスキャンしたものです。市電や原爆ドームは、数百枚以上の写真から生成した3D Gaussian Splattingを使っています。

本トピックでは、PLATEAUの3Dモデルをリアルに見せる方法、スキャンした3Dモデルを組み合わせる方法、物理演算によって風を作り、物体が建物を避けて流れるアニメーションの作り方などを解説します。

【メモ】

Gaussian Splattingは、ガウス分布に基づくぼかし効果を持つ球体によって対象を表現する手法です。本映像作品では処理上の理由から、Gaussian Splattingしたデータを単純な球体の集合として実装しています。詳細については、後編の「38.4 3Dスキャンと組み合わせてディテールアップする」の節をご参照ください。

制作には、統合3DCGソフトウェアのHoudini(フーディニ)のバージョン20.5を使っています。小規模なプロジェクトからハリウッド映画まで、映像制作の現場で使われているソフトウェアです。有償のソフトですが、非商用の個人的なプロジェクトであれば、Apprentice版を無償で使えるため、本チュートリアルの内容を実際に試せます(書き出し解像度などの制限があります)。

Houdiniは「ネットワークエディタ」と呼ばれるウィンドウで作業を進めるのが特徴です。オブジェクトに対して「作る」「変形する」「色を着ける」といった操作をノードとして定義し、それらを組み合わせていきます。この仕組みにより、オブジェクトをひとつひとつ手作業で編集しなくても、まとめて操作を適用したり、あとから簡単に修正したりできます。このチュートリアルでは、こうしたHoudiniの特徴を活かしながら、PLATEAUの3D都市モデルを扱っていきます。

このTOPIC37は、次の「TOPIC38 3Dスキャンデータとの組み合わせと物理シミュレーション」と併せて2本立てです。

TOPIC37では、ミニチュアルックの場面作り(下記①②③)を扱います。そしてTOPIC38では、よりリアルにするためのディテールアップ、そして、物理演算を用いた大規模アニメーションについて(下記④⑤⑥)解説します。

① 3D都市モデルの読み込みと軽量化の工夫

まず、PLATEAUの3D都市モデルを読み込む方法を説明します。HoudiniではOBJ形式やFBX形式のファイルを読み込めるため、読み込むこと自体は簡単です。しかしPLATEAUの3D都市モデルは大きく、そのままだと作業が重いため、軽量化したり、ふだん作業しているときには、テクスチャを表示しないようにしたりする工夫を解説します。

LOD1の建築物モデルにテクスチャを付ける

本映像作品で扱っている地域は、広範囲です。一部、LOD1のモデルしか提供されていない地域もあります。LOD1のモデルには、テクスチャが貼り込まれていません。そこで、汎用的なビルのテクスチャをあらかじめ用意しておき、それを貼り込んで、リアルに見せる方法を解説します。

【メモ】

LOD(Level Of Detail)とは、モデルの詳細度のことです。LOD1は直方体のモデル、LOD2はテクスチャがあり屋根も表現されたモデル、LOD3はさらに窓やドアなどの開口部まで表現したモデルです。詳しくは「TOPIC 3|3D都市モデルデータの基本[3/4]|LODレベルによる表現の違い」を参照してください。

図37-1 LOD2のモデルは全体のごく一部

③ ミニチュアルックの映像を作る

本映像作品では、ミニチュアルックらしい映像を作るため、ティルトシフトレンズを模した方法でカメラを設定しています。その考え方を紹介します。

既存モデルを配置することによるディテールアップ

広島市の3D都市モデルは年度が比較的新しいためテクスチャが鮮明なのですが、よりディテールアップするため、屋上にエアコンの室外機などのアセットを配置して、よりリアルにします。また窓を凹ませたり、木々を生やしたりすることで、リアル感を増す方法を紹介します。

3Dスキャンデータを組み合わせることによるディテールアップ

近年は、手軽に3Dスキャンできる環境が整いつつあり、作品に3Dスキャンした実写を使うことがしやすくなってきています。

本映像作品で用いている「もみじ饅頭」や「お好み焼き」は、LiDARスキャンしたものです。また、市電や原爆ドームのシーンは、数百枚以上の写真から生成した3D Gaussian Splattingを使っています。PLATEAUの3D都市モデルと、こうした3Dスキャンしたデータを組み合わせる方法を紹介します。

図37-2 建物や道路はPLATEAU。走る市電や一部地面は3D Gaussian Splattingで3Dスキャンしたもの

スケールの大きな物理シミュレーションの実現

本映像作品では、建物から大量のレモンが吹き出したり、風が吹いて、もみじ饅頭がやってきたりするシーンがあります。これらは、Houdiniの物理シミュレーション機能を用いて表現しています。その方法を紹介します。

図37-3 風に乗ってやってくる、もみじ饅頭

37.2 _ 3D都市モデルを読み込んで基本的なシーンを作る

まずはHoudiniで、3D都市モデルを読み込んで、基本的なところを整えて、シーンを作るところまでを説明します。

37.2.1 _ 3D都市モデルの読み込みと整理

広島市の3D都市モデルをHoudiniに読み込みます。本作品では、LOD2およびLOD1の建築物モデル(広島駅前のごく一部の建物のみLOD3)、そして、LOD2の地形モデル(DEMモデル)を使いました。提供されているPLATEAUの3D都市モデルをOBJ形式やFBX形式に変換すれば、そのままHoudiniでインポートできますが、ポリゴン数が多いため、インポート後に整理して、ポリゴンを削減する操作が必要です。

またPLATEAUの建築物モデルは建物数が多いため、そのまま扱うと、編集画面であるビューポートの動作が重くなります。これは建物ごとに異なるテクスチャが貼られており、その読み込みに時間がかかるのが理由です。そこで、ビューポートではテクスチャを読み込まず、レンダリングするときだけテクスチャを読み込むことで、軽快に編集作業できるようにします。

【メモ】

ビューポートでは、テクスチャ表示をオフにもできますが、オフにしても読み込まれるため、重い状況は変わりません。テクスチャそのものを読み込まないようにしなければ、軽快にはなりません。

■ OBJ形式への変換

まずはPLATEAUの3D都市モデルを、Houdiniで読み込めるように変換します。今回は、PLATEAU SDK for Unityを使って、OBJ形式に変換したものを使いました。

使用した領域は、広島市を中心とした図37-4のとおりです。この範囲の「地形モデル(DEM)」と「建築物モデル(BLDG)」を、それぞれ、OBJ形式に変換しておきます。

図37-4 今回使用する3D都市モデルの範囲

■ OBJ形式データをインポートする

OBJ形式のデータを用意したら、Houdiniのネットワークエディタで、次のように操作してインポートします。

【手順】 OBJ形式データをインポートする

[1]Labs OBJ Importerノードを作成する

ネットワークエディタで右クリックし、[Labs OBJ Importer]を選択して配置します。

【メモ】

ノード名に含まれる文字を入力すると、そのノードに絞り込まれます。例えば、[Labs OBJ Importer]は、「obj」などと入力すると見つけやすいです。

図37-5 Labs OBJ Importerノードを配置する
コラム:SideFX Labsの追加

Labs OBJ Importerノードは、Houdiniに付属するツールセットの「SideFX Labs」に含まれています。デフォルトでは有効化されていないので、メニューの一番右の[+]ボタンをクリックして追加してください。詳細な手順は、チュートリアル動画を参照してください。

図37-6 SideFX Labsを追加する

[2]地形(DEM)の3D都市モデルをインポートする

まずは、地形のインポートから始めます。配置したLabs OBJ Importerノードの[File]の部分をクリックして、地形のOBJ形式ファイルを選択してください。すると、インポートが始まります。完了までには、しばらく時間がかかります。

図37-7 地形ファイルを読み込む

[3]ポリゴン数などを確認する

読み込んだ地形が、ビューポートに表示されます。表示が縞模様になっており、uvが貼られていることがわかります。

まずはノード情報ウィンドウから、ポリゴン数などを確認しましょう。ノードの上にマウスポインタを置くと表示されるリングで[i]ボタンをクリックすると(もしくは、[Ctrl]キーを押しながらノードを中央ボタンクリックすると)、ノード情報ウィンドウを表示できます。

【メモ】

uvとは、テクスチャを貼り付けるときの向きを指定する座標のことです。

図37-8 ノード情報ウィンドウで確認したところ

■ ポリゴンを削減する

読み込んだ直後は、ポリゴン数が相当多いことがわかります。このままだと動作が重いので、ポリゴンを削減します。

【手順】ポリゴンを削減する

[1]PolyReduceノードを追加する

ネットワークエディタで右クリックし、PolyReduceノードを追加します。追加したら、Labs OBJ Importerノードと接続します。

図37-9 PolyReduceノードを追加する

[2]削減するパーセンテージを設定する

PolyReduceノードのパラメータウィンドウを操作し、[Percent To Keep]パラメータに対して、ポリゴン削減後のパーセンテージを設定します。ここでは「20」に設定し、20%まで削減することにしました。

この処理には、しばらく時間がかかります。削減が終わったら、先ほどと同様にノード情報ウィンドウを開き、ポリゴン数が削減されたことを確認します。

図37-10 [Percent To Keep]パラメータに対して削減するパーセンテージを設定する

■ テクスチャの情報を確認する

こうして読み込んだ3D都市モデルには、テクスチャが貼られています。このまま操作すると動作が重いので、ビューポート上で作業するときには、テクスチャを読み込まないようにします。

それに先立ち、ジオメトリの詳細を確認できるGeometry Spreadsheetペインを開き、現在のテクスチャの状態を確認しておきましょう。

【手順】テクスチャの状態を確認する

[1]Geometry Spreadsheetペインを開く

[Windows]メニューから[New Floating Panel]を選択し、新しいフローティングパネルを開きます。

新しいフローティングパネルが開いたら、[+]をクリックして、[New Panel Tab Type]から[Inspector]―[Geometry Spreadsheet]を選択します。

図37-11 Geometry Spreadsheetを開く

[2]テクスチャの情報を確認する

Geometry Spreadsheetでは、ポイントの座標やuv、テクスチャの情報を確認できます。[Primitive]に切り替えて表示を確認すると、そこにはmaterial_overrideというアトリビュートがあるのがわかります。

material_overrideアトリビュートのどこかのセルを右クリックするとInspectウィンドウが開き、詳細を確認できます。このbasecolor_textureの部分にテクスチャのパスが格納されていることがわかります。

図37-12 [Primitive](左から3番目のボタン)をクリックすると、material_overrideアトリビュートがあるのがわかる
図37-13 Inspectウィンドウで確認したところ。テクスチャのパスが格納されている

■ テクスチャ情報を待避して、ビューポートで読み込まれないようにする

こうした構造であることを利用して、ビューポートで作業するときにはテクスチャを読み込まず、レンダリングのときだけ読み込むという仕組みを作っていきます。

いまInspectウィンドウで見たように、Houdiniでは、material_overrideアトリビュートに設定されているテクスチャ情報を読み取ります。そこで、このmaterial_overrideアトリビュートを別名でコピーして削除してしまえば、テクスチャが読み込まれなくなります。レンダリングするときには、コピーした情報からテクスチャのパス情報を取り出して再設定することで、テクスチャが表示されるようになります。

以下の手順では、まず、material_overrideアトリビュートをdという名前の一時的なアトリビュートにコピーします(dという名前は任意です)。このdアトリビュートから、テクスチャのパス名が記述されているbasecolor_textureの値を別のtex_pathアトリビュートにコピーし、material_overrideアトリビュートとdアトリビュートを削除します。この時点で、ビューポートではテクスチャが読み込まれなくなります。

レンダリングするときは、このtex_pathアトリビュートに格納されているパス名をレンダラに設定することで、テクスチャが読み込まれるようにします。

【メモ】

ここではtex_pathアトリビュートに保存していますが、保存する際のアトリビュート名は任意です。

図37-14 ビューポートでの作業時にテクスチャを読み込まず、レンダリング時だけ読み込む仕組み

具体的には、次の操作をして、tex_pathアトリビュートにテクスチャのパス名を設定し、使用しないアトリビュートを削除するところまでを作っていきます。

【手順】テクスチャのパス名をtex_pathアトリビュートに移す

[1]Point Wrangleノードを追加する

Point Wrangleノードを追加し、Poly Reduceノードの下に接続します。接続したら、パラメータウィンドウで、[Run Over]パラメータを[Points]から[Primitives]に変更します。

図37-15 Point Wrangleノードを追加し、[Run Over]を[Primitives]に変更する

[2]material_overrideアトリビュートを別のアトリビュートにコピーする

[VEXpression]パラメータに、material_overrideアトリビュートの内容を、別のアトリビュートにコピーするVEXスニペットを記述します。ここでは、次のコードを入力します。

#define BSLASH chr(92)
#define FSLASH chr(47)


string json_str = s@material_override;


dict d = json_loads(json_str, 0);
s@tex_path = replace(d["basecolor_texture"],BSLASH,FSLASH);

上記のコードでは、まず、material_overrideアトリビュートの値を文字列として取得し、json_loads関数を用いて、ディクショナリ型に変換したものをdアトリビュートへと格納しています。そして、そのdアトリビュートのbasecolor_textureアトリビュートの値をtex_pathアトリビュートへと代入します。material_overrideアトリビュートでは、パス文字の区切りがバックスラッシュ(文字コード92番)なのですが、この区切り文字だと、あとでテクスチャを再設定するときに都合が悪いので、replace関数を用いて、スラッシュ(文字コード47番)に置換しています。

図37-16 VEXpressionパラメータにVEXスニペットを記述する

[3]テクスチャのパスを取り出せたことを確認する

Geometry Spreadsheetを開き、結果を確認します。tex_pathアトリビュートに、テクスチャのパスが(バックスラッシュはスラッシュに置換された状態で)格納されたことを確認できます。

図37-17 テクスチャのパスを取り出せた

[4]不要なアトリビュートを削除する

次に、不要なアトリビュートを削除します。Attribute Deleteノードを追加して接続します。そしてパラメータウィンドウで、不要なアトリビュートを削除するように構成します。

① [Delete Non Selected]にチェックを付けます。そうすると、選択していないアトリビュートが削除される動作に変わります。

② [Point Attributes]の部分で、点の座標を示す「P」とuvの座標を示す「uv」を指定します。

③ [Primitive Attribute]の部分で、いま追加した「tex_path」を選択します。

上記の設定をすることで、「P」「uv」「tex_path」のアトリビュートだけが残り、他のアトリビュートは削除されます。すなわち、もともとあったテクスチャ情報を示しているmaterial_overrideアトリビュートが消えるため、Houdiniのビューポートでは、テクスチャが読み込まれなくなります。

図37-18 「P」「uv」「tex_path」以外のアトリビュートを削除する

■ グループを削除する

続いて、ポイントやプリミティブ、エッジ、頂点のグループを削除して、軽量化します。 そのためには、Group Deleteノードを追加して接続します。今回は、すべてのグループを削除するため、[Group Names]パラメータには、すべてを示す「*」と入力します。

図37-19 グループをすべて削除する

■ キャッシュをとる

以上で、ひととおりの下処理が終わりました。インスペクタで確認すると、ポリゴン数やグループ数が削減されたことがわかります。

図37-20 インスペクタで確認したところ

次の操作に入る前に、File Cacheノードを追加して、キャッシュを取っておきましょう。キャッシュをとっておくと、ここまでの処理がキャッシュとして保存されるため、このシーンを開き直したときに再計算せずに済み、すぐに作業を再開できるようになります。

File Cacheノードでは、次のパラメータを設定します。

・[Time Dependent Cache]のチェックを外します。
このシーンは時間に動きがないためです。

・[Base Name]と[Base Folder]には、キャッシュを保存するファイル名やフォルダ名を設定します。
任意のファイル名、フォルダ名を指定してください。

・[Load from Disk]にチェックを付けます。
ディスクから読み込まれるようになります。

パラメータを設定したら、[Save to Disk]をクリックして、キャッシュを作成します。

図37-21 File Cacheノードを追加する

■ 建築物モデルを読み込む

地形の読み込みは、これで完了です。次に同様の方法で、建築物モデルを読み込んでいきます。

【手順】建物を読み込む

[1]Labs OBJ Importerノードを配置する

ネットワークエディタ上に、新しくLabs OBJ Importerノードを作成して配置します。配置したら、[File]の部分をクリックして、あらかじめPLATEAU SDK for Unityなどで変換しておいたOBJ形式の建築物モデルのファイルを選択します。読み込みが完了すると、ビューポートで、実際に建築物モデルが表示されるのを確認できます。

図37-22 Labs OBJ Importerを追加し、建築物モデルのOBJ形式ファイルを読み込む
図37-23 ビューポートで確認したところ

[2]地形と同じように軽量化する

地形と同じ処理を適用します。ただし、建築物モデルに対しては、PolyReduceノードを用いたポリゴン削減はしません。地形モデルと比べてそこまで大きくなく、ポリゴンを削減することによって建物の形状が変化してしまう問題があるためです。

ここで行うのは、ビューポートでテクスチャを読み込まないようにする処理だけです。すなわち、material_overrideアトリビュートのbasecolor_textureを別のtex_pathアトリビュートにコピーして、material_overrideアトリビュートを削除する処理を作ります。

ネットワークエディタでは、一連のノードをコピーできるので、地形のときに作った処理ノード群をコピーして、貼り付け、建物の処理のほうにつなぐのが簡単です。

具体的には、まずマウスで「Point Wrangleノード」「Attribute Deleteノード」「Group Deleteノード」を選択し、[Ctrl]+[C]キーでコピー、[Ctrl]+[V]キーで貼り付けます。

そして、いま配置したLabs OBJ Importerの下に接続します。

図37-24 Point Wrangle、Attribute Delete、Group DeleteをコピーしてLabs OBJ Importerの下に接続する

[3]キャッシュをとる

最後に、File Cacheノードを追加して、この一連の処理をキャッシュとして保存しておきます。

図37-25 File Cacheノードを追加する
コラム:複数の建築物モデルを扱う

 建築物モデルのファイルは3次メッシュ単位(およそ1km範囲)で分割されています。そのため広範囲を扱いたいときは、必然と複数のファイルを扱うことになります。その場合は、Labs OBJ Importerノードをファイルの数だけ用意し、その出力をMergeノードでひとまとめにします。

図37-26 Mergeノードでひとまとめにする

37.2.2 _ LOD1の建物にテクスチャを貼る

本映像作品で扱っている範囲には、LOD1のモデルとLOD2のモデル(ごく一部の建物のみLOD3のモデル)が混じっています。LOD1のモデルにはテクスチャが貼られていません。

どの建物にテクスチャが貼られていて、どのテクスチャに貼られていないのかは、ビューポートで確認できます。uvが設定されている建物(縞模様が付いているもの)がLOD2以上のモデル、uvが設定されていない建物がLOD1のモデルです。

図37-27 uvが設定されている建物(LOD2以上)とuvが設定されていない建物(LOD1)

■ uvの有無で処理を分ける

以下では、テクスチャが貼られていない建物に対して、テクスチャを貼り付けていきます。まずは、テクスチャを貼る必要があるかの判定、すなわち、uvが設定されているか否かで処理を分けるフローを作っていきます。

【手順】uvの有無で処理を分ける

[1]Point Wrangleノードを追加する

建物の3D都市モデルを処理している一連のノードの下に、Point Wrangleノードを追加します。

図37-28 Point Wrangleノードを追加する

[2]uvの有無を判定する処理を書く

Geometry Spreadsheetで確認するとわかるのですが、uvを持っているものは「tex_pathアトリビュート」が設定されています。そこで、このアトリビュートの有無で判定します。

【メモ】

tex_pathアトリビュートは、3D都市モデルに含まれるアトリビュートではありません。ビューポートでテクスチャを読み込まずに軽量化するときにPoint Wrangleノードを使って作成した、テクスチャのパス名を格納したアトリビュートであり、本トピック内で私たちが作ったアトリビュートです。

図37-29 Geometry Spreadsheetで確認すると、tex_pathアトリビュートの有無で判定できることがわかる

そこでいま設置したPoint WrangleノードのVEXpressionパラメータに、次のコードを記述することで、tex_pathアトリビュートの有無によってグループ化します。このコードによって、tex_pathが空欄であったときに、no_textureグループが1に設定されます。

if(s@tex_path=="")i@group_no_texture = 1;
図37-30 VEXpressionパラメータの設定
図37-31 設定後にGeometry Spreadsheetで確認したところ
コラム:テクスチャの有無を可視化する

Colorノードを使うと、条件によって色分けできます。例えば、図37-32のようにGroupパラメータにno_texture、Colorパラメータに赤色を設定したColorノードを配置すると、no_textureグループが1であるオブジェクト(つまりテクスチャが設定されていないオブジェクト)が、赤くなります。

図37-32 可視化したところ

[3]グループ分けする

いま設定したno_textureグループで処理を分けるため、Splitノードを追加します。追加したSplitノードの[Group]パラメータに「no_texture」と設定して、no_textureの値で分岐するように構成します。

図37-33 Splitノードを追加する

[4]Nullノードを設置する

Splitノードは処理を2つに分岐します。条件に合致するものが左側、合致しないものが右側です。すなわち左側に流れるのがテクスチャなし(no_textureグループが設定されているものなので)、右側に流れるのがテクスチャありのフローです。この2つの出力について、このあとそれぞれ加工する処理をさらに作るため、接合点としてNullノード(何も操作しないノード)を配置しておきます。前者をno_texture、後者をwith_textureという名前に変更しておきます。

図37-34 出力にNullノードを配置する
図37-35 名前を変更したところ

■ 屋根と側面とで分ける

こうして分けた、テクスチャが貼られていないもの(no_texture側)について、テクスチャを貼る処理を作っていきます。

今回は、屋根の部分と側面とで処理を分けました。PLATEAUの3D都市モデルでは、地面(DEM)に航空写真(オルソ画像)が貼られているため、屋根には、その航空写真を貼り付けます。そして側面に対しては、別途、汎用的なビルの窓のテクスチャをいくつか用意しておき、それをランダムに貼り付けることにします。

この2つの処理を分けるため、まずは、ポリゴンが屋根なのか、側面なのかで処理を分けます。

【手順】屋根と側面とを分離する

[1]面の向きでグループ化する

屋根なのか側面なのかは、面の向きで判断できます。そこでまずは、向きでグループ化します。

Group Createノードを追加し、[Group Name]に「top」と入力します。[Keep by Normals]を[Enable]とし、[Direction](向き)を、「0, 1, 0」とします。こうすることで、面の向きが「0, 1, 0」の方向(上向きの面)の場合、topグループが1に設定されるようになります。

【メモ】

PLATEAUのLOD1のモデルは直方体のモデルであるため、屋根が斜めであることはありません。

図37-36 Group Createノードを追加したところ

[2]Splitで分離する

Group Createの下にSplitノードを配置し、Groupパラメータにtopを選択します。これで屋根の部分とそうでない部分(側面)に分離できます。

図37-37 Splitで分離する

■ 屋根に地形の航空写真のテクスチャを設定する

こうして分離した屋根側(Splitの左側)に対して、屋根のテクスチャを貼る処理を作っていきます。

PLATEAUの地形(DEM)の3D都市モデルには航空写真のテクスチャが含まれているので、地形から該当のテクスチャを参照して、貼り付けていきます。

【手順】屋根に地形と同じテクスチャを貼る

[1]地形のデータを参照する

まずは、Object Mergeノードを配置して、地形のジオメトリを参照します。そのためには、Object Mergeノードを配置し、[Object 1]パラメータに対して、地形のオブジェクト(キャッシュ済みのもの)をドラッグ&ドロップします。

図37-38 Object Mergeノードを追加し、Object1に地形のジオメトリをドラッグ&ドロップする

[2]屋根を最も近い地面に投影する

次に、テクスチャを投影するためのRayノードを配置します。Rayノードの1番目の入力には、テクスチャを付けたい屋根の面、2番目の入力には、いま配置したObject Mergeノードを接続します。

そして、さらに次のパラメータを設定します。

・Methodパラメータを[Minimum Distance]に変更する
最も近い地面に投影されるようになります。

・Import Attribute from Hitsパラメータを有効にする
[Import Attribute from Hits]パラメータを有効にします。有効にすることで、投影先の面のアトリビュートがインポートされます。
インポートする項目として、[Point Attribute]に「*」(すべて)を選択し、[Primitive Attributes]に「tex_path」を設定します。そうすることで、(uvを含む)すべての点情報ならびにtex_pathアトリビュートがインポートされます。

図37-39 Rayノードを配置する

[3]uvアトリビュートをコピーする

Rayノードでそのまま投影すると、高さがあるため位置がズレます。そこでuvアトリビュートだけをコピーして、位置(ポイント)の情報は使わないようにします。

Attribute Copyノードを配置して、1番目の入力に屋根の面、2番目の入力にRayノードの出力をつなぎます。そしてパラメータを、次のように設定します。

・Attribute Nameに「uv」を設定する
uvアトリビュートがコピーされるようになります。

図37-40 uvアトリビュートをコピーする

[4]tex_pathをコピーする

同様にして、tex_pathアトリビュートをコピーします。同じように、Attribute Copyノードでコピーすればよいのですが、tex_pathアトリビュートはPointアトリビュートであるため、そのままAttribute Copyノードに接続するとエラーが発生します。

そこでAttribute Promoteノードを間に挟み、PointアトリビュートからPrimitiveアトリビュートに変換したうえで接続します。

図37-41 tex_pathアトリビュートをコピーするように設定したAttribute Copyノードを接続する
図37-42 Attribute PromoteノードでPointからPrimitiveに変換してから接続する

■ 側面の重複点をまとめる

以上で、屋根に対するテクスチャの貼り付けは終わりです。続いて、側面にテクスチャを貼り付けていきます。

まずは、屋根と側面に分けたSplitノードの右側(側面側)にNullノードを配置して、ここからスタートしましょう(このNullノードをクリックして選択すれば、ビューポートで側面の部分だけを可視化できます)。

さて、この建物ですが、拡大して[ポイントナンバーを表示する]ボタンをクリックして詳細を見ていくと、面の頂点が同じ場所にもかかわらず、1点で構成されているのではなく、複数の点が同じ場所に重複しているのがわかります。

そこでFuseノードを配置して、こうした重複点を1点にまとめます。もう一度、ビューポートで確認すると、今度は、そうした重複点がひとつにまとめられたことがわかります。

図37-43 Nullノードを配置してビューポート上で、ポイントナンバーを確認したところ
図37-44 Fuseノードを配置して重複点をまとめた

■ 側面に建物のテクスチャを付ける

では、この側面のひとつひとつに建物のテクスチャを付けていきます。PLATEAUの建築物モデルは建物数が多いため、こうした貼り付けを手作業で行うのはたいへんですが、Houdiniなら、繰り返し処理を使うことで、まとめて貼り付けられます。

作業に先立ち、建物のテクスチャをあらかじめ用意しておきます。今回はTextures.comから、適当な58種類のテクスチャを用意しました。これらのテクスチャは、あらかじめダウンロードし、bldg_1.JPG、bldg_2.JPGのように連番を付けて保存しておきます。

図37-45 使用した建物のテクスチャ
図37-46 連番を付けて保存しておく

【手順】建物の側面にテクスチャを付ける

[1]For Each Connected Pieceを配置する

繰り返し処理するため、「For Each Connected Piece」を配置します。すると、繰り返しのための一連のノードが配置されます。

図37-47 For Each Connected Pieceを配置する
図37-48 繰り返し処理のための一連のノードが配置された

[2]uvを貼る

まずは、uvを貼ります。UV Unwrapノードをforeach_beginとforeach_endの間に配置します。これで、uvが貼られます。

図37-49 UV Unwrapノードを配置する

[3]ランダムな値を生成する

次に、テクスチャを貼る処理を加えていきます。

今回は58枚のテクスチャを用意しており、これらを建物ごとにランダムに貼っていきます。そこでまずは、建物ごとに1~58のランダムなIDを割り当てます。そのためには、Attribute Randomizeノードを配置し、次のように設定します。

・ランダムなIDの設定

まずはAttribute Nameを「tex_rand_id」、Attribute Classを「Primitives」として、プリミティブ型のtex_rand_idという名前のアトリビュートとします。最小値と最大値は、それぞれMin ValueとMax Valueで指定します。ここでは前者を1、後者を58に設定します。

これらの設定により、tex_rand_idアトリビュートに、1~58の範囲のランダムな値が設定されるようになります。のちの処理で、この番号を基に、テクスチャファイル名「bldg_1.JPG」「bldg_2.JPG」を生成します。

図37-50 ランダムな値を生成する

・建物ごとに同一の番号にする

1つの建物で異なる建物のテクスチャが貼られるのはおかしいので、同一の建物ならランダム値が同一になるようにします。そのために、[Options]をクリックし、Seed Attributeパラメータに「class」と入力します。Seed Attributeパラメータは、ランダムな値を生成するシード(種:たね)を設定するもので、同一のシードであれば、ランダム値が同一になります。つまり、この設定により、classが同じなら発生するランダム値も同じ値になります。

指定したclassは、For Each Connected Piece を追加したときに先頭に追加されたConnectivityノードで構成されるデフォルトのアトリビュートで、ループするたびの連番となります。ループ処理は建物ごとに行っているため、割り振られる値も建物ごとの連番です。ですからclassをSeed Attributeパラメータとして設定することで、同じ建物であれば、どの面でも同じランダムな値が割り当てられるようになります。

図37-51 Optionsを設定する

[4]テクスチャのファイル名を設定する

生成したtex_rand_idアトリビュートを用いて、テクスチャのファイル名を作ります。

ここまでテクスチャ付きのオブジェクト(LOD2の範囲)では、テクスチャのファイル名をtex_pathアトリビュートに設定しています。ですから、テクスチャなしのオブジェクト(LOD1の範囲)でも、同じくtex_pathアトリビュートにテクスチャのファイル名を格納すれば、レンダリング処理を作るときに、同じように扱えるので都合が良いです。

そこで、Attribute Wrangleノードを配置して、VEXpressionパラメータに次のコードを入力します。

s@tex_path = chs("texture_folder") + "bldg_"+itoa(i@tex_rand_id)+".JPG"

このコードには「chs("texture_folder")」という部分があります。コードを入力したあとに右上の[パラメータ作成]ボタンをクリックすると、Texture Folderというパラメータ欄が表示されるので、ここにテクスチャを格納したフォルダを入力します。このとき、フォルダ名は、逆スラッシュ(半角の¥マーク)ではなくスラッシュで区切りとしてください。

なおファイル名は、ここでは、「bldg_番号.JPG」というファイル名としています。このファイル名は、あらかじめ用意した建物のテクスチャのファイル名に合わせてください。

図37-52 tex_pathアトリビュートを生成するためのAttribute Wrangleノードを配置し、VEXpressionパラメータを設定する
図37-53 Texture Folderパラメータに実際のフォルダ名を入力する

[5]確認する

Geometry Spreadsheetで確認すると、tex_pathアトリビュートに1~58のいずれかのJPGファイルが設定されていることがわかります。

図37-54 tex_pathアトリビュートが設定された

[6]不要なアトリビュートを削除する

最後にAttribute Deleteを配置して、不要なアトリビュートを削除しておきます。「P」「uv」「tex_path」以外を削除します。

図37-55 「P」「uv」「tex_path」以外を削除する

■ 建物全体をマージする

以上で設定完了です。最後にマージします。

【手順】マージする

[1]屋根と側面をマージする

Mergeノードを配置して、まずは、「屋根」と「側面」をマージします。

図37-56 「屋根」と「側面」をMergeする

[2]「テクスチャなし」と「テクスチャあり」をマージする

 同様にして、「テクスチャなし」と「テクスチャあり」をマージします。

図37-57 「テクスチャなし」と「テクスチャあり」をマージする

37.2.3 _ Karmaでレンダリングする

以上で、3D都市モデルの下準備が整い、現在、次の状態になっています。

・地形(地面)のジオメトリがあります。
uvとtex_path(これは航空写真です)が設定されています

・建物のジオメトリがあります。
LOD1とLOD2が混じっていますが、どちらにもuvとtex_path(LOD2の場合はPLATEAUで提供されているもの、LOD1の場合は、屋根は地面の航空写真、側面は58種のビルのテクスチャのうちの1つ)が設定されています

これらをHoudiniでレンダリングする処理を記述してきます。Houdiniでは、Karmaというレンダラを使います。

■ レンダラの種類

Karmaのレンダラには、「Karma CPU」と「Karma XPU」の2種類があります。前者はCPUのみでレンダリングするもの、後者はGPUも併用してレンダリングするものです。XPUのほうが高速ですが、GPU性能に大きく依存するため、自身の制作環境に合わせて使い分けましょう。

やり方は少し異なり、CPUのほうが少し簡単です。

以下では、まず、Karma CPUのやり方を説明し、次に、Karma XPUを使うやり方に変更する方法を順に説明します(今回の作品制作では、Karma XPUを使っています)。

■ レンダリング対象を読み込む

Houdiniでは、LOP Networkノードを配置し、そのなかでレンダリング対象のものを参照するというやり方でレンダリングします。まずは、この下準備をしましょう。

【手順】LOP Networkノードを配置する

[1]地形の出力にNullノードを配置して名前を付ける

LOP Networkノードから参照しやすくするため、地形の出力にNullノードを配置して名前を付けます。ここでは「OUT_ground」という名前を付けました。

図37-58 地形の出力を「OUT_ground」とする

[2]建物の出力にNullノードを配置して名前を付ける

同様に、建物の出力にもNullノードを配置して、「OUT_bldg」という名前を付けます。

図37-59 建物の出力を「OUT_bldg」とする

[3]LOP Networkを配置する

最上位階層に戻り(ネットワークエディタの[obj]の部分をクリックすると戻れます)、LOP Networkを配置します。

図37-60 LOP Networkを配置する

[4]地形を読み込む

配置したLOP Networkをダブルクリックして、階層のなかに入ります。そして、SOP Importを配置します。ここではgroundという名前に変更しました。

【メモ】

ノードの名前は、名前が表示されている部分をダブルクリックすると変更できます。

SOP Pathの部分で参照したいジオメトリを選択します。右側のボタンをクリックするとChoose Operationウィンドウが表示されるので、先ほど作成したOUT_groundを選択します。これで地形が読み込まれます。

図37-61 SOP Importを配置して、OUT_groundを選択する
図37-62 地形が読み込まれた

[5]建物を読み込む

同様にして、建物を読み込みます。SOP Importを配置して、OUT_bldgを選択します。これで建物も読み込まれました。

図37-63 建物を読み込む

[6]マージする

Mergeノードを配置して、地面と建物をマージします。

図37-64 地面と建物をマージする

■ カメラとライトを配置し、マテリアルを作れるようにする

レンダリングには、カメラとライトが必要なので配置します。また、マテリアルを作るためのMaterial Libraryも構成します。

【手順】カメラとライトを配置する

[1]カメラを配置する

ウィンドウ左上の[Camera]ボタンをクリックします。すると、カメラが配置されます。

図37-65 カメラを配置する

[2]ライトを配置する

続いてライトを配置します。ライトはカメラと違って、ネットワークノード上で右クリックメニューから追加します。今回は、Karma Physical Skyノードを使いました。配置すると、空が青っぽくなります。

図37-66 Karma Physical Skyノードを配置したところ

[3]Material Libraryを作成する

このあとマテリアルを作っていくのですが、そのためには、Material Libraryノードが必要なので、配置します。

図37-67 Material Libraryノードを配置する

■ Karma CPUの場合の構成

では、マテリアルを作成していきます。まずは、CPUの場合から説明します(XPUの場合は、CPU用に作成したものに手を加えます)。

マテリアルは、Material Libraryノードの内部で操作して作成します。作成したMaterial Libraryノードをダブルクリックして、その階層のなかに入ってから、以下の作業をします。

【手順】マテリアルを作る(CPUの場合)

[1]Karma Material Builderを作る

Material Libraryノードの階層のなかに入り、まずはKarma Material Builderを作ります。するとSubnetworkが作られます。作られたSubnetworkの名前をgroundとしました。

図37-68  Karma Material Builderを作る
図37-69 Subnetworkが作られる。groundという名前に変更した

[2]テクスチャを設定する

作られたSubnetworkをダブルクリックして階層のなかに入ります。すると、さまざまなノードが見つかります。

このうちのMtlX Standard SurfaceのBase入力の配下にあるbase_colorパラメータにテクスチャを設定すると、そのテクスチャが表示されるようになります。

図37-70 Subnetworkノードをダブルクリックして階層のなかに入ったところ

テクスチャを作成するため、新たにUSD UV Textureノードを作り、そのrgb出力をbase_colorパラメータに接続します。

図37-71 USD UV Textureノードを作成する
図37-72 rgb出力をbase_color入力に接続する

[3]tex_pathアトリビュートからテクスチャのファイル名を参照する

USD UV Textureノードのfileパラメータにテクスチャのファイル名を指定すれば、そのファイルがテクスチャとして設定されます。ここまでの構成で、テクスチャのファイル名は、tex_pathアトリビュートに格納されています。ですから、この値を参照するように構成します。

そのためには、USD Prim Var Readerノードを配置します。Signatureを[String]に設定し、Var Nameには「tex_path」を設定すると、tex_pathアトリビュートの値を取得できます。それをUSD UV Textureノードのfileパラメータにつなぎます。

図37-73 tex_pathアトリビュートの値を取得して、それをfileパラメータへと渡す

[4]uvを渡す

同様にuv情報も渡します。MtlX Texture Coordinatesノードを作り、その出力をuvパラメータへと接続します。

図37-74 MtlX Texture Coordinatesノードを作り、その出力をuvパラメータへと接続する

[5]マテリアルを割り付ける

上の階層に戻り、Material Libraryノードの下にAssign Materialノードを配置します。

配置したら、PrimitivesパラメータとMaterial Pathsパラメータを設定します。どちらも、Geometry SpreadsheetのScene Graph Pathからドラッグ&ドロップして設定します。設定すると、ビューポートでの表示が白くなります。白くなる理由は、テクスチャが設定されているけれども、ビューポート上では、読み込まれていないのが理由です(テクスチャは、ビューポートでの表示のときではなく、レンダリングのときに読み込むよう、その処理をあとで作成していきます)。

図37-75 Assign Materialノードを配置する
図37-76 PrimitivesパラメータとMaterial Pathパラメータを設定する

[6]建物についても同様に構成する

建物についても、同様に構成します。まずは、(Karma Material Builderを作ることで作られた)Subnetworkをコピーします。コピー後の名前はbldgとしました。

図37-77 Subnetworkをコピーし、名前をbldgに変更した

[7]建物のマテリアルも割り当てる

Assign Materialノードに対して、このbldgも構成します。[+]ボタンをクリックすると項目が増えるので、bldgをドラッグ&ドロップして構成します。

図37-78 Assign Materialノードにbldgの項目を追加する
コラム:マテリアルをオフにする

ここまでの操作によって、ビューポート上ではテクスチャが設定されているけれども読み込まれていない状態になるため、画面が真っ白になり、建物がわかりづらくなります。白黒のボックスのボタンをクリックしてマテリアルをオフにすると、真っ白ではなくなります(図37-79)。

なお、微調整したいときはビューポート上でもテクスチャを表示したいこともあるでしょう。その場合は、選択されているオブジェクト群に関するテクスチャだけを読み込むような処理ノードを記述します。その方法については、次のTOPIC 38の「38.2  選択している箇所のテクスチャを表示する」で解説します。

図37-79 ビューポートでマテリアルをオフにする

■ レンダリング処理を作る

次に、レンダリングの処理を作っていきます。

【手順】レンダリング処理を作る

[1]Karmaを配置する

Karmaを追加します。すると、Karma Render SettingsとUSD Render ROPノードが作られます。これらを先ほどの出力の後ろにつなげます。そして、Karma Render Settingsを有効にするため、クリックしてフラグを立てます。

図37-80 Karmaを配置する
図37-81  Karma Render Settingsをクリックしてフラグを立てる

[2]レンダリングする

ビューポートの右上でカメラからのビューに切り替えます。さらにPerspectiveを[Karma CPU]に変更します。

するとレンダリングされ、テクスチャが表示されます(レンダリングを元に戻すには、Perspectiveを[Houdini VK]に変更します)。

【メモ】

テクスチャが表示されないときは、ビューポートでマテリアルがオフになっていないか(コラム「マテリアルをオフにする」を参照)を確認してください。

【メモ】

ライトを明るくして見やすくする方法については、本トピック冒頭のチュートリアル動画で解説しているので参考にしてください。

図37-82 カメラからのビューに切り替える
図37-83 Karma CPUに切り替える
図37-84 テクスチャ付きでレンダリングされた

■ Karma XPUの場合の準備

Karma XPUを使う場合は、さらに作業が必要です。テクスチャのパス名ごとにジオメトリをグループ分けする必要があります。

まずは次のようにして、テクスチャ名ごとに連番のパス名を作ります。

【手順】テクスチャパスの名前ごとに連番のパス名を作る

[1]For Each Connected Pieceを追加する

地面の出力の下に、[For Each Connected Piece]を追加します。すると、Connectivityノード、foreach_begin、foreach_endの各ノードが追加されます。

図37-85 For Each Connected Pieceを追加する
図37-86 繰り返し処理のためのノード一式が追加された

[2]tex_pathでループするように変更する

先ほどの例では、classでループしましたが、今回は、tex_pathでループしたいため、自動的に作られたConnectivityノードを削除します。

そして残ったforeach_begin、foreach_endを出力に挟み込みます。Piece Attributeは選択項目しか選べませんが(ラベルが緑色の表示)、[Ctrl]+[Shift]+クリックすると自由入力できるように(ラベルが白色の表示)なるので、そのようにしてから、「tex_path」と入力します。これで、foreach_begin、foreach_endの間が、tex_path単位でループするようになります。

図37-87 Connectivityノードを削除したところ
図37-88 tex_pathでループするように構成する

[3]tex_pathごとに連番のpath名を作る

tex_pathごとに連番のpath名を作ります。Attribute Wrangleをbegin~endの間に配置し、VEXpressionパラメータに、次のコードを記述します。このコードは、「/Geometry/ground_mesh_」という文字列の後ろに、Attribute Wrangleの左から2番目の入力(detail(1, "iteration")の「1」に相当。入力は、左から0番、1番、・・・となるため、「1」は左から2番目を指す)の連番をつなげた文字列をpathアトリビュートに設定するコードです。

s@path = "/Geometry/ground/mesh_"+itoa(detail(1, "iteration"));
図37-89 pathアトリビュートにtex_pathごとの連番パス名を設定するコードを書く

まだこの段階では、左から2番目の入力に何もつながっていないので、この入力を作ります。

beginのノードをクリックして選択状態にし、パラメータウィンドウの[Create Meta Import Node]をクリックします。すると、その右にMeta Importノードが作られます。

図37-90[Create Meta Import Node]をクリックする
図37-91 Meta Importノードが作られた

Meta Importノードをクリックし選択状態にして、Geometry Spreadsheetで確認すると、DetailのIterationが「0」と表示されているのがわかります。これは、「いま繰り返している回数」を示しており、先ほどコードに書いた「detail(1, "iteration")」で取得しようとしている値です。

図37-92 Geometry Spreadsheetで確認したところ

このMeta ImportノードをAttribute Wrangleの左から2番目に接続します。そうすると、先ほどのAttribute Wrangleのコードからこの値を取得できるので、pathアトリビュートの値が、tex_pathごとに、「/Geometry/ground/mesh_0」「/Geometry/ground/mesh_1」・・・と設定されるようになります。その様子は実際に、foreach_endの部分をクリックして選択状態にした状態でGeometry Spreadsheetを見ると、確認できます。

図37-93 Meta Importノードの出力をAttribute Wrangleの左から2番目につなぐ
図37-94 Geometry Spreadsheetでpathアトリビュートを確認したところ

[4]建物についても適用する

いま作成したforeach_begin~foreach_endの部分を建物に対しても適用します。まずは、範囲選択して[Ctrl]+[C]キーを押してコピーします。そして、建物の出力の後ろにこれを貼り付けて接続します。

図37-95 コピーする範囲
図37-96 建物の出力のところに貼り付けて接続した

[5]パスを変更する

先ほどのVEXpressionパラメータに指定した式では、パス名をgroundとしていますが、建物のほうでは、これをbldgに変更します。

図37-97 パスをgroundからbldgに変更する

■ Karma XPUを使ったレンダリング処理

このようにpathアトリビュートに、テクスチャファイル名ごとに連番のパスを格納するように構成したら、次のようにして、レンダリング処理を調整します。

【手順】Karma XPUを使ったレンダリング処理

[1]XPU用のMaterial Libraryを作る

Karma CPU用に作成したLOP Networkのなかに入り、Material Libraryを作って接続します。

図37-98 Material Libraryを作って接続する

[2]Karma Material Builderを作る

いま配置したMaterial Libraryをダブルクリックして階層のなかに入って、レンダリング処理を調整していきます。まずは、Karma Material Builderを作ります。するとSubnetworkが作られます。わかりやすく名前をgroundに変更します。

図37-99 Karma Material Builderを作ったところ(Subnetworkが作られる)

[3]MtlX Imageを配置する

Subnetworkをダブルクリックしてなかに入り、MtlX Imageノードを追加します。そしてoutを、MtlX Standard Surfaceのbase_colorに接続します。

図37-100 MtlX Imageノードを追加して、outをbase_colorに接続する

[4]テクスチャのファイルを選択する

MtlX Imageのfileパラメータにテクスチャのファイルを設定します。fileパラメータのところにマウスポインタを合わせてマウスホイールを押し込むとメニューが表示されるので、[Promote Parameter]を選択します。

すると、パラメータがノードとして外に出るように構成され、その場所に小さな四角形が表示されます。ダブルクリックすると、fileパラメータがノードとして現れます。

fileパラメータは区別しやすいように、Nameをtexture_path、LabelをTexture pathに設定しておきます。

図37-101 [file]のところでマウスホイールを押し込む
図37-102 [Promote Parameter]を選択する
図37-103 四角形ができるのでダブルクリックする
図37-104 fileが現れた
図37-105 NameとLabelを設定する

[5]マテリアルを割り当てる

LOP Network階層に戻り、MaterialLibraryの下にAssign Materialを配置します。

この時点でGeometry Spreadsheetsを確認すると、groundの下にmesh_0、mesh_1のように分かれていることがわかります。あとはKarma CPUのときと同じように、PrimitivesとMaterial Pathにそれぞれ設定します。前者は「/Geometry/ground/*」、後者は「/materials/ground」です。さらにサブディレクトリに分かれているため、前者では「/*」を指定し忘れないようにします。

図37-106 Assign Materialを配置する
図37-107 Geometry Spreadsheetで確認したところ
図37-108 PrimitivesとMaterial Pathを設定する

[6]texture_pathにtex_pathを代入するように調整する

これまで作ってきた処理では、テクスチャのパス名をMtlX Imageのfileパラメータに入れ込むtexture_pathアトリビュートに設定すれば、そのテクスチャが表示されるように作っています。本トピックでこれまで作ってきたモデルでは、テクスチャのパス名がtex_pathアトリビュートに設定されていますから、この値をtexture_pathアトリビュートに設定するように構成します。

そのためには、[Parameters Overrides]で[Vexpression]を選択し、次のコードを[Override Vexpression]に入力します。

string primpath = @primpath;
string textureAttrib[] = usd_primvar(0, primpath, "tex_path");
s@texture_path = textureAttrib[0];
図37-109 texture_pathにtex_pathを代入するように調整する

[7]Karmaを作る

Karmaを作って配置します。そして、[Engine Settings]を[XPU Parameters]に変更します。

図37-110 Karmaを作り、[XPU Parameters]に変更する

[8]レンダリングして確認する

ビューポートで[Karma XPU]を選択して確認します。地形に対してテクスチャが適用されたことがわかります。

図37-111 レンダリングして確認したところ

[9]建物にも適用する

同様にして、建物にも適用します。まずは、Subnetworkをコピーして貼り付けます。ここでは名前をbldgに変更しました。

図37-112 複製する。名前はbldgとした

[10]マテリアルのアサインを追加する

LOP Networkの階層内に戻り、Assign Materialノードの[+]をクリックして設定項目を増やします。そして、Primitivesには「/Geometry/bldg/*」、Material Pathには「/materials/bldg」を設定します。

また、[Parameters Override]と[Override Vexpression]についても同様に設定します。

図37-113 建物のアサインを設定する

[11]レンダリングして確認する

ビューポートで[Karma XPU]を選択して確認します。正しくレンダリングされたことがわかります。

図37-114 Karma XPUでレンダリングしたところ

37.3 _ ミニチュアルックの表現

次に、ミニチュアルックを表現する方法について説明します。

37.3.1 _ ミニチュアルックとは

一般的にミニチュアルックとは、カメラを上から俯瞰した位置に設置し、手前と奥がボケていて、映したい対象のものに対して、ハッキリと焦点が合っているような構図です。こうした構図でレンダリングすると、ミニチュアらしく見えます。

ミニチュアルックを作るには、焦点距離を指定する簡易な方法と、ティルトシフトレンズを用いた方法があります。前者は遠近法によって建物がゆがむのに対して、後者は垂直に立っているように見えるため、よりミニチュア感が増します。

図37-115 ティルトシフト表現

37.3.2 _ 焦点距離の指定で表現する簡易な方法

まずは、ふつうにカメラを配置し、焦点距離を指定するだけで表現する簡易な方法から説明します。

■ 編集しやすくする

作業に先立ち、編集しやすく再構成します。

【手順】編集しやすく再構成する

[1]Geometryノードを作る

現在は、geo1のなかに、すべてのジオメトリがあります。これらを地形と建物で別々に操作できるように、新しくジオメトリを作って参照するように構成します。

まずは、Geometryノードを作成します。これは地形用とし、名前をgroundに変更します。

図37-116 groundという名のGeometryを作る

[2]Object Mergeノードを作る

作成したgroundをダブルクリックして階層に入り、Object Mergeノードを作ります。

図37-117 Object Mergeノードを作る

[3]地形をコピーする

geo1をダブルクリックして階層の内部に入り、地形を出力しているNullノードを選択し、[Ctrl]+[C]キーでコピーします。

図37-118 地形をコピーする

[4]Object Mergeから参照する

手順[2]で追加したObject Mergeの[Object 1]の欄で[Ctrl]+[V]キーを押して、手順[3]でコピーしたNullノードを参照するように構成します。

図37-119 Object Mergeから参照する

[5]建物用にコピーする

いま配置したgroundをコピーして、もうひとつGeometryを作ります。bldgという名前にします。

図37-120 複製してbldgという名前にする

[6]建物を参照する

先ほどの地形の例と同様に、建物を出力しているNullノードをコピーし、bldgの内部のObject MergeのObject1にコピーします。

図37-121 建物を出力しているNullノードをコピーする
図37-122 (bldg内部の)Object MergeのObject1に設定する

[7]地形と建物が分かれた

これでgroundを選べば地形、bldgを選べば建物というように、分けて作業できるようになりました。

図37-123 groundとbldgに分けて扱えるようになった

■ カメラを配置して位置を調整する

それでは、ミニチュアルックで撮影する方法を順に説明します。まずはカメラを配置して、位置を調整します。

【手順】カメラを配置して位置を調整する

[1]カメラを配置する

ウィンドウ左上の[Camera]をクリックして、カメラを配置します。

図37-124 カメラを配置したところ

[2]位置を調整する

ビューポートでロックマークのボタンをクリックすると、カメラの位置を調整できるので、映したい位置にくるように調整します。

図37-125 カメラの位置を調整する

■ 焦点距離を調整する

次に、カメラの焦点距離を調整していきます。

【手順】焦点距離を調整する

[1]カメラのロックを外してカメラと被写体となる建物が横から見えるようにする

ロックボタンをクリックしてロックを外します。すると、その場所でカメラが固定され、自由な視点で見られるようになります。

焦点距離の調整がしやすいよう、カメラと被写体となる建物が横から見えるような位置にビューポートの見た目を調整します。

図37-126 カメラが調整しやすいようビューポートでの見え方を調整する

[2]焦点距離を調整する

[Z]キーを押します。すると焦点距離を調整する線分が表示されます。四角形がボケの中心、両端の三角形が焦点の合う範囲です。

ミニチュアルックを表現するには、ビルなどの焦点を合わせたいところに四角形を合わせ、焦点の合う範囲を狭くします。

図37-127 焦点距離を調整する線分
図37-128 ビルに焦点を合わせ、三角で挟まれる部分を短くしてピントの範囲を狭める

■ カメラの映像を確認しながら調整する

設定したらカメラの映像を確認しながら、調整していきます。そのためには、いま配置したカメラで見られるようにします。

【手順】カメラで見られるようにする

[1]現在のカメラを削除する

LOP Networkのなかに入り、現在のカメラを選択し、[DELETE]キーを押して削除します。

図37-129 現在のカメラを削除する

[2]配置したカメラを読み込む

右クリックして、[Scene Import(Cameras)]を追加します。これは先ほどシーン上に配置したカメラです。このカメラを、先ほどカメラがあった位置に挿入します。

図37-130 [Scene Import(Cameras)]を追加する
図37-131 カメラを挿入したところ

[3]ビューポートで確認する

ビューポートでカメラを選択し、[Karma XPU](またはKarma CPU)を選択し、レンダリング結果を確認します。指定したビルに焦点が合い、それ以外はボケており、ミニチュアルックのようになっているのがわかります。必要に応じて、焦点距離やカメラの位置などを微調整します。

図37-132 ビューポートで確認したところ

37.4 _ ティルトシフトレンズを表現する方法

次に、よりミニチュアルックらしく映せる、ティルトシフトについて説明します。

■ ティルトシフトレンズを用いた方法

実写作品において、ミニチュアルックのような映像を撮影するには、ティルトシフトレンズを使うことが多いです。ティルトシフトレンズとは、レンズを傾けたり(ティルト)、ズラしたり(シフト)できる特殊なレンズです。前者はピントが合う範囲を調整できます。そして後者はパースペクティブのゆがみを調整できます。この2つを組み合わせることで、ミニチュア写真らしくなります。

図37-133 ティルトシフトレンズ

■ ティルトシフトレンズをHoudiniで実現する

ティルトシフトレンズをHoudiniで実現するには、次のようにします。

【手順】ティルトシフトレンズをHoudiniで実現する

[1]カメラを複製する

いったんカメラを複製しておきます。元のカメラはcam1_normal、複製したカメラはcam1_tiltshiftとします。以下、このcam1_tiltshiftに対して操作していきます。

図37-134 カメラを複製する

[2]ティルトの実現

ティルトを実現するには、単純に、カメラの角度を変えます。

図37-135 ティルトの実現

[3]シフトを実現する

シフトを実現するには、カメラの[View]ページにある[Screen Window X/Y]の[Y]の部分を調整します。

図37-136 [Screen Window X/Y]の[Y]でシフトを実現する

[4]ミニチュアルックらしく見えるように調整する

実際にティルトシフトレンズでミニチュア写真を撮影するときは、カメラの向きを被写体よりも上に上げて、シフト機能でレンズを下に向けるようにします。このような設定にすることで、ミニチュアルックらしく見えます(より細かい調整については、チュートリアル動画を参照してください)。

図37-137 カメラは上に向けてレンズを下にシフトするとミニチュアルックらしくなる

[5]レンダリングして確認する

レンダリングして確認します。先ほどの焦点距離のみを調整と異なり、建物が垂直に近いことがわかります。

図37-138 ティルトシフトで構成した場合

37.5 _ まとめ

このトピックでは、Houdiniを使ったPLATEAUの3D都市モデルの扱い方を説明しました。

Houdiniはネットワークエディタでノードを編集できるため、まとまった処理がしやすいです。PLATEAUは点の数もテクスチャの数も、そして、建物の数も多いため、本トピックで解説した方法でまとめて処理することで、省力化できます。無骨なLOD1の建物も、今回行ったように、屋根には航空写真を、側面には汎用のビルのテクスチャをランダムに貼り付けるだけで、見栄えが良くなることがおわかりいただけたかと思います。

次のTOPIC38では、さらに凹凸を付けたり、キットバッシュでディテールアップしたり、3Dスキャンしたオブジェクトと重ね合わせたり、シミュレーション機能を使って、大量のオブジェクトを風で流すようにしたりする手法を紹介します。

【文】

大澤文孝

【監修】

塚島 建(WOW inc.)