前回からの続き。どうやらBlenderではレンダリング時ピクセルに負の値を持てないらしく、Point WorldをそのままNukeに読み込んでも正しく3D空間でのピクセルの位置が再現できませんでした。今回はその暫定的な解決策を書いてみます。
負の値が持てないなら、前ピクセルが正の値になるように全体の座標をオフセットしてしまおうということです。もちろん3Dシーンをずらすのではなくレンダリング時にそうなるようにマテリアルシェーダーで設定します。
前回座標系の変換に用いたMappingノードにLocationがあるので、X,Y,Zのすべてに「10000.0」を入力します。もちろんシーンが10000以上の大きさならもっと大きくする必要がありますが、とりあえず10000もあれば大丈夫でしょう。
このシェーダーでレンダリングすると、当然ながらR,G,Bがすべて「+10000.0」になってしまうので(通常白が1.0)、振り切れて真っ白な状態でレンダリングされます。レンダリング画像はOpenEXR(あるいはMultiLayerのOpenEXR)で保存します。
余談ですが、Point WorldやNormalなどをレンダリングする際には、1ピクセルに正確に数値を格納するために、アンチエイリアスはオフにしておく必要があります。(隣のピクセルと混ざると正確な値でなくなる)
以上でBlenderでの作業は終わりです。これをNukeに読み込みます。今回はMultiLayerを使用したので、Shuffleノードでチャンネルを設定してます。先ほどBlenderで設定したオフセット値を元に戻します。今回はわかりやすくExpressionノードを個別に接続しています。
ExpressionノードではBlenderで加算したオフセット値を引いて元に戻します。これで負の値を含む正確なPoint Worldの値になり、画像もそれぞれのチャネルが色として見えるようになります。
Point Cloudで表示すると、ちゃんと負の座標も含めて再現されているのがわかります。
これでBlenderでPoint Worldの値を画像経由で出力する方法は終わりです。Blenderの場合はコンポジットまで内部でやること前提であまりこういう需要がないのかもしれませんが、一応NukeにPoint Pass出せたよ...というです。
[関連記事]