株式会社デジタル・フロンティア-Digital Frontier

Header

Main

  • TOP
  • DF TALK
  • NukeでのPositionPass有効活用法

NukeでのPositionPass有効活用法

2016/11/14

Tag: ,

前回の記事からだいぶ経ってしまいました、開発山口です。
今回はPosition Passを利用したDepth Passの作成方法を紹介したいと思います。
使い古されたネタかもしれませんがお付き合いください。

始めに

記事内の説明で使用しているNukeのシーンファイルですが、コピペしてシーン内に再現できるようにテキストを
用意しました。”expand source”をクリックしていただければ出てきますので記事と合わせて見てください。
※1度開いてしまうと閉じられないみたいなので、コピペが終わったらリロードしてください。
またNuke7.0以上のバージョンでお試しください。

nukescene

Position Passとは

Position Passとは、各PixelのRGBに対し、オブジェクトのXYZ値を格納したPassです。

positionpass

使い方は様々で、例えばNormal Passと組み合わせることで、影無しではありますが
簡易的なライティングをすることも可能です。

relight

PositionToPointsノードを使用することで、各Pixelの位置を3D空間上でどこにあるか
調べることもできます。

positiontopoints

このように様々な使用用途がある素材ですが、今回はこれを利用してNuke上でDepthを作成する
方法を紹介したいと思います。

Mayaからの出力

まずこのPassを作成する所から始めたいと思います。
Position Passはレンダラーで標準でサポートされているものも有りますが、今回は既存の
ノードを使用して出力してみたいと思います。
使用するレンダラーはmentalrayです

といっても、とても簡単でSurfaceShaderのOutColorにsamplerInfoノードのPoint Worldをつなぐだけです。
positionpassshader

あとはこれでレンダリングするだけでPosition Passが出力できます。
この際に気をつけてほしいのが出力設定で、必ず32bit floatで出力してください。

mentalraysettings

なぜこの設定がなぜこれでなければいけないのかは、次回あたりにでも記事にしたいと思います。
レンダリング結果をNukeで開き、各サーフェイスの値に1以上、0以下の値が入っていれば成功です。

高さDepth

hightdepthimage

では早速Depthを作成していきます。
まず高さDepthです。これはとても簡単です。

そもそもPosition PassにはGチャンネルに高さ情報が入っているので、これの
レンジを変えてあげるだけで簡単に作成できます。

ShuffleノードでGチャンネルだけ取り出し、GradeノードのBlackPointとWhitePointに
値を入れてあげるだけです。

hightdepth

奥行きDepth01

depth01image

次はカメラからのDepth素材です。
カメラからのDepth素材には円形のDepthと線形のDepthの2つがあります。

depthtype

まず、簡単なほうの円形のDepthを紹介します。

これも非常に簡単で各Pixelの位置情報からカメラの位置を引き算し、そのベクトルの距離を求め
レンジを調節してあげることで求めることができます。

depth01

任意のポジションからのDepth

positiondepthimage

これは奥行きDepth01の応用です。
カメラのポジションを任意のポジションに変えてあげるだけです。
Axisノードを使用して、それのポジション情報を使用すれば3D空間上で位置決めが楽になります。

positiondepth

奥行きDepth02

depth02image

最後に線形のDepthです。
数学の知識が無いとなかなか難しいですがチャレンジしてみてください。

下図の緑のベクトルの長さで、これを求めるにはその他にカメラから各Pixelまでのベクトルと
カメラからの視線ベクトルが必要です。

vector

この2つのベクトルを利用して、ベクトル間の角度を求め
三角関数のcosineを使用すれば緑のベクトルを求めることが出来ます。
thetacosine-1

では実際にNukeでの操作を見て行きたいと思います

2つのベクトルを作成

まず2つのベクトルを作成します。

1つめがカメラから各Pixelに向かうベクトルで、各Pixelの値からカメラのポジションを引き算することで求められます。
pixelvectornuke

2つめがカメラの視線ベクトルです。

カメラの視線ベクトルはアトリビュートのWorld Matrixの部分から作成することができます。
そもそもカメラベクトルは(0, 0, -1)とZがマイナスなので、視線ベクトルとしてはマイナスを掛けてあげる必要があります。
式はMatrix × Camera Vectorです。

ちょっと難しく思うかも知れませんが、下図のMatrixの値に-1を乗算してあげることで作成できます。

matrix

エクスプレッションにはこのように書きます。
※ここではあえてカラー値にしていますが、そのまま計算式として入れてしまってもいいです。

cameravectornuke

マイナスに変換したのは2つベクトルの方向を合わせるためです。
1つ目のベクトルの計算を”カメラのポジション”から”各Pixelの値”を引くように
計算式を変更しても最終結果は同じになります。

2つのベクトルのなす角を求める

2つのベクトルの間の角度は下記の計算式で求めることが出来ます。

gettheta

これをNukeのExpressionノード表現すると下図のようになります。

getangle

ベクトルの長さを求める

上の式から求められた角度と三角関数のcosine、カメラから各Pixelに向かうベクトルの長さの3つを
使用して、最終的なDepth値を求めます。

vectordistance

こんな書き方も

実は下記のようにacosとcosは打ち消すことが出来ます。

vectordistance

処理の流れとしては上の方がわかりやすいですが、わかってしまえば下の方のが計算処理が
速くなるので状況に応じて使い分けてください。

レンジ(Near,Far)の調整

このままでは、単純に3D上での距離が入っているだけですので
gradeノードを使用して、レンジ(Near,Far設定)を設定します

rangesettings

rangesettingsimage

以上で完成です。

Position Passは工夫すれば色んな使い方ができて、なかなか面白い素材です。
カメラの情報等別途必要になる物も有りますが、頑張って素材のHeaderに埋め込むなど
してしまえば、カメラの情報が無くても何とかなったりします。

ぜひ、皆さんも活用してみてください。


※免責事項※
本記事内で公開している全ての手法・コードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください。

コメント

😉

1 thought on “NukeでのPositionPass有効活用法”

  1. とんとこ より:

    😉

コメントフォーム

*

コメントは承認制ですので、即時に反映されません。ご了承ください。

CAPTCHA