NUKE の特徴であるマルチチャンネルは非常に強力だ。各種 3DCG ソフトウェアのマルチパスレンダリングとも、とても相性が良い。今回から前編と後編の2回に分けて、3DCG ソフトとの連帯について紹介していこう。前編では Autodesk 3ds Max と Autodesk Maya を用いて、簡単に複数のパスを出力する方法を紹介していく。

マルチチャンネルの活用とダイナミックレンジの有効性

最近の主な 3DCG ソフトでは、標準で様々なレンダーパスを出力することができるようになっている。

Mayaのレンダーパス

Mayaの例。ここにあるレンダーパスを全て一度のレンダリングで出力可能だ

以前、「Vol.2:続・AEユーザーのためのNUKE的思考」でも紹介したように、NUKE はそれらのレンダーパスを幅広く活用することができる。と言うのも、デフォルトで親ノード(もしくは B コネクト)から、チャンネルを自動的に引き継ぐようになっているためだ。これは、様々なチャンネルを親ノードに持っておいて、それを必要なときに呼び出して使うという NUKE の考え方によるもの。

例えば、モーションブラーについて見てみよう。NUKE ではポスト処理としてモーションブラー効果を表現することができる。

マクロス

wipe で、左が VectorBlur ノードの効果あり、右が元ソース。NUKEVectorBlur ノードを用いるにはモーションベクターが必要となる

3DCG ソフト側でモーションベクターを出力して、それを beauty パス(RGB パス)と一緒に持たせ、NUKE の VectorBlur ノードの[uv channels]でそのモーションベクターを指定してやる。

チャンネル指定

VectorBlur ノードのプロパティにある [uv channels] でモーションベクターのチャンネルを指定。スクリーンスペースのモーションベクターを使用する。また、u 値v 値 の設定により後述してるが 8bit 画像を使用することが可能だ

モーションベクターとは、各ピクセルがそのフレームにおいて、どの向きにどれくらいの速度で動いているかを示すもの。つまり、ピクセル単位ベクターの情報である。NUKE の VectorBlur で扱うモーションベクターは、スクリーンスペースのベクターであり、レンダリング画像である平面にその動きを落とし込んだものである。例えば、あるピクセルがスクリーン座標で右斜め 45 度に向かって動いていたとしたら、そのピクセルの持つモーションベクターは (r, g, b) = (1, 1, 0) のように表すことができる。

モーションベクター

例えば、右斜め45度方向に移動しているとすると...

モーションベクター

そのモーションベクターチャンネルはこのように (r, g, b) = (1, 1, 0) だったりする(※クリックで拡大)。Viewer ペーンの右下にピックした色が表示される。後述するが、(1, 1, 0) というのはあくまで一例だ

モーションブラー

そのモーションベクターに VectorBlur ノードを適用すると、モーションブラー効果を得ることができる

つまり、スクリーン座標の x,y がそれぞれ、r,g で表されているわけだ。このように、スクリーン座標系のモーションベクターだと rg で座標が表され、通常、b は使用されない。先ほどの例では便宜上 (r, g, b) = (1, 1, 0) としたが、右斜め上 45 度は、その速度によっては (0.1, 0.1, 0) かもしれないし、(10, 10, 0) という場合もある。いずれにせよ、ベクターなので向きと大きさを持っている。

ピクセル

具体的にレンダリングされたモーションベクターチャンネルを見てみると、あるピクセルでは (0.35132, 0.38452, 0) となっていた(画像)。また別のピクセルでは (1.87109, 0.36206, 0)、さらに別のピクセルでは (-6.10938, 1.79688, 0) という具合だった

ピクセル

画像の場合、モーションベクターの red チャンネルが 1(255) を超えている

ピクセル

さらに、こちらの画像の場合は red チャンネルにマイナスの数値(-6.10938)が入っている

以上の結果から、日頃、慣れ親しんでいる 0-1(0-255) の値を超えた数を扱う必要があるわけだ。とは言ったものの、実は "必要がある" というのは言い過ぎで、例えばマイナスの扱いを見てみると、(1, 0, 0) のモーションベクターと (-1, 0, 0) のモーションベクターだと、デフォルト値で VectorBlur を与えると結果は同じになる。

Shuffle ノードを加える

Constant ノードで擬似的にモーションベクターを作成し、それを Shuffle ノードを用いて元の画に新たなチャンネルとして加えてみた(※クリックで拡大)。Constant ノードでは (r, g, b) = (1, 0, 0) としている

Constant ノードを調整

先の例の反対のベクターになるように、Constant ノードで (r, g, b) = (-1, 0, 0) としたが、VectorBlur ノードのプロパティの値がデフォルトのままであると、結果は同じだった(※クリックで拡大

また、xy 座標で (0.5, 0.5) を起点にすれば 0-1 の範囲で全方向を示せるので、詳しい説明は割愛するが VectorBlur のプロパティを調整することで、0-1 の画像......つまり 8bit の画像でも対応は可能だ。

ただし、モーションベクターのスカラーは 1 を超えないように調整する必要があったりと、諸々の問題もあるので、ダイナミックレンジでピクセルの値を持てる方が何かと都合は良い。ポスト処理で被写界深度を表現するために必要なデプスや、beauty を再構築するためによく使うリフレクションパスなども、0-1 に制約されないほうが便利である。なお、筆者のブログ 「TIRAOKAN.」 では、Beauty の再構築についてもう少し説明しているので興味ある方は併せてご覧頂ければと思う。

デプスチャンネルを確認

デプスチャンネルを見てみると、例では黒の部分にもマイナスの値が存在してちゃんと「階調」が存在している。NUKE ではその「階調」を利用して [ZBlur] ノードで被写界深度の効果を追加することが可能だ

長々と説明してきたが、32bit や 16bit のファイルのように、ダイナミックレンジを扱えて、かつ、各種レンダーパスを1つのファイルとして格納できる OpenEXR ファイルフォーマット は NUKE と相性が良く、非常に効果的だ。

 16bit half float でレンダリング

今回の作例では OpenEXR を用いて 16bit half float でレンダリングしているが、この場合だと NUKE で [Read] ノードで読み込んだ時点で colorspace がデフォルトで linear になる。.jpg や .tga のような 8bit 画像だとデフォルトで sRGB で読み込まれる

[[SplitPage]]

Autodesk 3ds Max 編

ここからは、Autodesk 3ds Max を用いてモーションブラーと被写界深度を NUKE で表現するためのモーションベクターとデプス、さらに、RGB マスクを OpenEXR を用いて1つのファイルで出力する方法を紹介していこう。また、NUKE で 32bit、16bit の画像を用いると、デフォルトでリニア画像として読み込まれ、3D ソフトウェア側ではガンマ値 =1 の画像として出力する必要があるので、これに関しても合わせて解説していく。なお、3ds Max のレンダラーには V-Ray を使用した。

AOCs で保存

今回の作例ではレンダリング出力としてマルチレイヤーを用いることのできる OpenEXR でレンダリングし、各チャンネルは AOVs で保存した

レンダリングした画像を NUKE で読み込む際、通常、jpg や tga のような 8bit 画像は、その [Read] ノードの colorspace を sRGB として読み込む。しかし今回は、各チャンネルをマルチレイヤーとして格納し、複数のレンダーパスを 1 ファイルとして扱うため、OpenEXR を使用した。この場合は、linear として読み込まれる。

colorspaceのデフォルト値

NUKE では OpenEXR を読むと自動的に colorspace が linear になっている( tga などの sRGB 画像では同じく自動的に sRGB となる)

ここで注意が必要なのだが、linear で読み込むということは、3ds Max 側でファイルガンマ「1」で保存する必要がある。ただ、3ds Max のデフォルトではたとえ保存ファイルが OpenEXR であっても、ファイルガンマ「2.2」として保存されるようなのだ。それを回避するためには、[menu→Rendering→Gamma/LUT Setup...] より、[Enable Gamma/LUT Correction] にチェックを入れておく。こうすることで、レンダリング画像の保存の際に、gamma が選択できるようになる。

ガンマの設定 ガンマの設定

メニューから[Rendering→Gamma/LUT Setup...] を選択。設定ウィンドウにある [Enable Gamma/LUT Correction] にチェックを入れる

ガンマの設定

デフォルトだと保存される画像のファイルガンマは 2.2 なので、Overrideで 1.0 を指定

これで準備は完了なので、次にチャンネル保存の設定を行う。各チャンネルは 3ds Max の標準機能であるレンダーエレメントを使えば、スペキュラやデプスというような、通常は出力に少し工夫がいるレンダーパスも予め用意されているため、それらを一回のレンダリングでまとめて出力することが可能だ。

レンダーエレメント

標準の Scanline レンダラーにも数多くのエレメントが準備されているが、V-Ray の場合はコンポジットにも役立つ特殊なエレメントが数多く準備されている

作例ように、RGB マスクで出力したいものが 4 種類ある場合は、オブジェクトチャンネルとしてそれぞれ 1~4 を割り当てるが、RGB マスクで一度に分離することができるのは 3 種類(黒を用いれば 4種類だが)なので [MultiMatteElement] を 2 度使い、それぞれを
[MultiMatteElementA.red]
[MultiMatteElementA.green]
[MultiMatteElementA.blue]
[MultiMatteElementB.red]
としている。

つまり、MultiMatteElementA として、[red][green][blue]を設定した上で、今回は 4 種類なので、それとは別に [MultiMatteElementB] を設けてそれの [red] としてもう1つチャンネルを設けて、4つに割り当てたわけだ。

ObjectIDの割り当て

オブジェクトの種類ごとにオブジェクトプロパティから異なる ObjectID を与えてやる

MultiMatteElementの登録 MultiMatteElementの登録

RGB の 3 つチャンネルでは 3 つまでしかマスクが取得できないので、さらに、別のチャンネルとして MultiMatteElement を登録する

続いて、モーションブラー用のベロシティチャンネルと、被写界震度用のデプスチャンネルを設定する。エレメントはそれぞれ、[VRayVelocity]と、[VRayZDepth] 。注意点としては、共に clamp のチェックを外すことだ。

MultiMatteElementの登録 MultiMatteElementの登録

clamp にチェックが入っていると、値が 0-1(0-255) に制限されてしまう。そのシーンで深度(カメラからの距離)、ベロシティ共に最大値を予め計算しておいて設定すれば、値をカットせずに用いることもできるが、NUKE の利点である 32bit をフル活用するのであれば、Clamp のチェックを外して、それらのチャンネルを利用する

ベロシティチャンネル とは、スクリーンベースでピクセル毎にブラーの方向を指定するようなものなので、マイナス値で表現されるピクセルもあり、ダイナミックレンジでの保存が不可欠である。また、同様にデプスチャンネルもシーンによっては深度をある一定のところでクランプ(限定)してしまうと、動的なシーンでは随時その「一定」の数値を更新していく必要があるが、これもダイナミックレンジであることを利用し、クランプしない状態で出力することが可能だ。

[[SplitPage]]

Autodesk Maya 編

続いて、同様のレンダーパスの書き出しを Autodesk Maya から行う場合について解説しよう。まず、Maya からマルチレイヤーの OpenEXR を出力する場合だが、大前提としてマルチレイヤー OpenEXR 出力に対応しているレンダラを使わなければならない。そこで今回は、Maya のデフォルト環境で使用できる mental ray を使用した OpenEXR の出力に関して解説していくことにした。

Maya と mental ray でマルチレイヤー OpenEXR を出力する場合、Maya 標準のレンダーパスを使用するのが一番簡単だ。

mental rayに切り替え

レンダラをデフォルトの [Maya software]から[mental ray]に変更することで、Render Setting ウィンドウ内に Passes のタブが確認でき、そこから各種レンダーパスにアクセスができる

レンダーパスは mental ray でのみ使用でき、出力に OpenEXR を選択しレンダーパスを使用することで、簡単にマルチレイヤーの OpenEXR ファイルが出力される。今回は実際に、デプス、モーションベクター、オブジェクトマスクの 3 つを出力してみたい。

マルチレイヤーの使用

出力設定を OpenEXR に設定して1つのファイルで複数のレンダーパスを持たすことのできるマルチレイヤーを用いる

1.レンダーパスの作り方

レンダーパスを作成するには、まず mental ray がロードされていることを確かめるため、[Window→Settings/Preferences→Plug-in Manager] を実行し、Mayatomr がロードされていることを確認。ロードされると RenderGlobals の Render Using で選択可能になるので、レンダラを mental rayに切り替える。

プラグインの読み込みを確認

デフォルトでプラグインが読み込まれていない場合があるので、その場合 [Plug-in Manager] から確認し、[Load]にチェックを入れて読み込ませる

Passes タブに移り、右上にある[Create Render Passes]をクリック。すると、下の画像のようなウィンドウが現れる。リスト表示されているのが、Maya で作成できるレンダーパスだ。

プラグインの読み込みを確認

mental ray がデフォルトで持っているレンダーパスたち。前述したように、これら全てのパスを一度のレンダリングで出力できる

今回の作例では、次の 4 つを作成していく。

・Camera Depth
・2D Motion Vector
・Custom Color ×2

それぞれデフォルトでは depth, mv2DToxik, customColor, customColor1と、非常に分かりづらい名前になっているので、適宜名前を変更していこう。

<変更前→変更後>
・depth → depth(深度情報)
・mv2DToxik → mv2D(2D ブラー用モーションベクター)
・customColor → objectMaskA(オブジェクトマスク用)
・customColor1 → objectMaskB(オブジェクトマスク用)

レンダーパスの作成はこれで完成。depth は深度情報、mv2D は 2D ブラー用のモーションベクター、objectMaskA, B はオブジェクトのマスク用のパスだ。これらを実際に使用するには、[Scene Passes]ではなく、[Associated Passes] に登録する必要がある。登録すると、レンダーパスが [Scene Passes] から [Associated Passes] に移る。

MultiMatteElementの登録 MultiMatteElementの登録

出力したいパスを上段の [Scene Passes」 から選んで [Associate selected passes with current render layer] のボタンを押すと、下段の [Associated Passes」 に移る。こうすることで実際にそれらのパスがレンダリングされる。上段の [Scene Passes] に登録しただけではレンダリングされないので要注意

また、レンダーパスはシェーダごとに対応状況が異なる。 使用しているシェーダがレンダーパスに対応しているかどうかは、Mayaユーザガイドのマルチレンダーパスを参照にすると良い。

2.レンダーパスの設定

今回の作例では、depth と mv2D はデフォルトのまま使用する。これらはデフォルトで 32bit float の情報として格納されるようになっており、何か理由がない限り、レンダーパスの設定自体をいじる必要はない。ただし、モーションベクターに関しては、レンダーパスを有効にした時点でモーションブラーが自動で ON になる。詳しくは後述するが、その際、モーションブラー OFF の時の画とはオフセット分だけ異なった仕上がりにレンダリングされるので、これを回避するには少し設定を変える必要がある。

また、objectMaskA, B に関しても、そのままで問題なし。ただし、これらは簡単なオブジェクトマスクレイヤーなので、Frame Buffer Type8bit integer に変更しても良いだろう。ちなみに、オブジェクトマスクは Custom Color Buffer を使用するため多少設定が必要となるが、この方法も後述する。

3.モーションブラーの設定

前述した通り、モーションベクターのレンダーパスを使用する場合、レンダー時に自動でモーションブラーが ON になる。その結果、モーションブラーなしの画像と異なる結果の画像がレンダリングされてしまう。これを回避するためには、[RenderGlobals][Quality→Motion Blur] から、モーションブラーを ON にし、[Shutter Open] および [Shutter Close] の値を共に 0.5 とし、予めモーションブラーの設定を変えておく。

 Motion Blurの調整

Quality タブの Motion Blur の項を調整

このように設定を変えることで、モーションブラーがかかっていないものと極めて近い結果を得ることが可能だ。

 Motion Blur有無の比較

モーションブラーの有り無しを比べたもの。重ねてみるとスペキュラなどに若干の違いが確認できるが、運用を間違えなければ問題なく使用出来るレベルだろう

[[SplitPage]]

4.オブジェクトマスクの設定

Maya では前述した 3ds Max のように、オブジェクトに指定した ID から簡単にオブジェクトマスクを作り出すということができない。そのため、自分で好きに情報を出力することができる Custom Color バッファを使用する。

今回は、オブジェクトマスクをそれぞれ適切に出力するために、出力させたいまとまりごとに異なったマテリアルをアサインしてある。つまりこの手法は、厳密にはオブジェクトマスクではなく、マテリアルマスクの出力となる。方法としては、まず writeToColorBufferノード を作成。それに対し、以下のようにパラメータをセットする。

レンダーパスと色の関連付け レンダーパスと色の関連付け

ハイパーシェードから mental ray を用いて [writeToColorBuffer] を設定し、Attribute Editor にてさらにレンダーパスと色を関連付けた(※クリックで拡大

次に、オブジェクトマスクを作成したいオブジェクトに割り当てられたシェーダとコネクトする。

writeToColorBufferに関連付け

さらにシェーダを writeToColorBuffer に関連付ける

今回は、mia_material_x_passes を使用しているが、BlinnPhong などを使用する場合は result ではなく outColor を接続。これらを各オブジェクト(マテリアル)に対し、適宜 RGB を変更しながら設定していくことで、望みどおりのオブジェクトマスクが得られる。
なお、上の状態だと writeToColorBuffer は output を行なっておらず、ネットワーク的に宙に浮いた状態となってしまっているため、Delete Unused Nodes などを使用すると不要とみなされ削除されてしまうため注意が必要だ。

5.リニア環境の設定

OpenEXR でレンダリングを行うため、リニア環境でライティングを行なっていく。リニアワークフローの説明は、色に関する大変深い話になってしまうので、詳しく述べるのは避け、ここでは簡単にその手順だけを紹介していこう。

まず、[Render View → Display → 32-bit floating-point (HDR)]を ON にし、Maya を再起動。この手順を踏むと、Render View で直接 float の画像が表示できるようになる。逆に何もしないままだと、思わぬ結果が出てしまうことがあるため、真っ先に行うべきだ。続けて、[Render View → Display → Color Management]を実行し、画像(下)のようにのように設定する。

ガンマの設定を確認

この設定を行うことで、レンダリングされたリニア画像を sRGB 空間で表示させることが可能になる

これらを適切に作用させるためには、Render Globals でのガンマの設定が適切なものである必要がある。[Common → Color Management → Default Output Profile] が Linear sRGB になっていること、そして [Quality → Framebuffer → Gamma]が 1.0 になっていること、という以上2点を確認しておこう。

writeToColorBufferに関連付け

Color Management はデフォルトのままであれば問題ないが、Framebuffer の設定は各自行う必要がある。またその際、Data Type も「RGBA(Half) 4x16 Bit」に変更することで、カラーの出力が 16bit float になるので、一緒に設定しておこう。デフォルトの RGBA(Byte) 4x8 Bit のままでは、Tiff や Targa に出力するのとなんら変わりのない 8bit 画像が出来てしまうだけなので要注意だ(※クリックで拡大

6.OpenEXR に含めるレイヤーの名前

ここまでで、ほとんどの設定は完了したのだが、最後に、OpenEXR に含めるレイヤーの名前の変更を行う。デフォルトでは、RenderGlobals の [Common → File Output → Frame Buffer Naming] が Automatic になっている。この場合、例えば、DIFF:diffuse.persp、CAMZ:depth.camera1 などという感じに、「:.」 というルールでレイヤーの名前付けが行われる。しかしこれでは冗長な上にパッと見で分かりづらいので、名前を変更するわけだ。Frame Buffer Naming を「Custom」にすると、「Custom Name String」の編集が行えるようになる。

レイヤー名の変更

Frame Buffer Naming を「Custom」にすると、「Custom Name String」の編集が行えるようになる。これにより、最初に設定した depth, mv2D, objectMatteA などの名前がレイヤー名として用いられるように

Maya と 3ds Max を例にとって紹介をした「各 3D ソフトウェアとの連帯・前編」はいかがだったろうか? 次回は、Autodesk Softimage、Houdini(Side Effects Software)、MAXON CINEMA 4D 以上の 3DCG ソフトとの連携方法について解説する予定だ。

TEXT_テラオカマサヒロ(Galaxy of Terror)
株式会社ギャラクシーオブテラーにて VFX ディレクターとして活躍中。実写合成からフルCGまで、幅広いVFX制作に携わっている。
個人サイト「tiraokan. 」

TEXT(Autodesk Maya編)_taikomatsuCGブログ「memlog」 管理人)