2010-08-02

Nuke Mergeの説明

まことに未熟者ですが、CGWORLD.JP にて 、「Nukeプラクティカル・ガイド」 が始まりました。
この「tiraokan」でも補完補足を行っていきたいと思っております。

で、第一回目はNuke的概念というか、思考というか、それをメインにつらつらと書かせてもらったため、じゃあ実際どうやって使うのか?ってところで疑問が多々生まれるであろうと想像しております。
当然、今後、時間を掛けて実際の使用方法を紹介していくつもりではありますが、今回は、基本的なことを列挙してみます。

まず、「Merge」・・・

通常左にあるツールバーっぽい、Nodesペーンから呼び出すか

 NodeGraphペーン上で右クリックして呼び出すか

NodeGraphペーン上でtabキーを押して、直接NodeOpの名前を打ち込むか
 
AfterEffectsでいうところのレイヤーを重ねるという行為です。ちなみに、ショートカットは[m]です。

この「tiraokan」でも最初の方に説明していましたが、MergeNodeOperatorにはインプットが「A」と「B」と通常二つ確認することができます。とりあえず、2枚の画像を合成してみます。


こんな感じです。Bがバックグラウンド。Aがフォアグラウンドです。で、この場合、AmbOccの画像で、GIライクな陰影をつけたいという意図なので、フォアの乗せ方を[multiply](乗算)に変更します。
「Properties Bin」にある、この「Merge1」の[operation]をデフォルトの[over]から[multiply]に変更します。


これで、AmbOccを [multiply]で合成することができました。
viewerペーンに何も出ないという場合は、


見たいNodeOpをViewerOPにつないで下さい。


こんな感じで。 この場合「Merge1」NodeOPを選んでキーボードの「1」を押すと、ViewerOPの一番に「Merge1」の出力がコネクトされます。

また、OpenEXRを用いると、AOVとして各種レンダリングパスを画像1枚に格納できます。


その場合、たとえば、同じ画像にある[rgb]チャンネルと[AmbOcc]を合成する場合は・・・


真ん中にある●は「Dot」と呼ばれるもので、ラインの流れ(チャンネルの流れ)を
わかりやすくするために、用いたりします。この場合使わなくていけますが・・・

こんな風にひとつの画像を[Merge1]のAとBにコネクトして、


[Merge1]のPropertyで


[A channels]を[ambocc]に変更してやり(この場合この画像にあらかじめamboccのチャンネルが存在します)、


 おなじく[operation]を[multiply]に変更してやればOK。
こっちのほうが、Nuke的でスマートです!

2010-06-03

Relighting その2

その1からの続きです。
前回は標準のReLightNodeを用いて、Relightingを行いました。ただ、このRelightingの結果を直接add mixなどでのせても味気ないので、もう一味つけるためにもReflection Mappingを施したいと思います。

Reflection Mappingに関しては、以前も一度投稿してます。 PworlrdとNworldとカメラの情報さえあれば、Nukeの中でReflection Mappingができちゃいます。やり方は、OpenGLなどでは、割と有名は方法らしいのですが(OpenGLの大家の床井先生も紹介されていました)、LTEの藤田さんに、ものすごく丁寧にご教授いただきました。その内容を説明したいとおもいます。

※注意 バカ丁寧に細かく説明しているので、長ったらしい内容になってますが、ヨクヨク読めば、たいしたないようではありません。根気よく読んでもらえればと。

原理的には、ジオメトリ上の任意の点にカメラからみてどちらの方向へ反射するかで、さらに、その反射を球体マッピング的な環境で出してしまおうという感じです。
カメラからの視線を入射角として、その視線が当たる点の法線から反射角を求め、さらにそれをuv mappingに置き換えるという手法です。

まずは、 カメラの位置とPworldから、視線ベクトル(入射角)を求めます。
Pworldは、平たく言えば各ピクセルの位置情報です。当然座標なんて本来8bitの色情報である0-255に収まらないのですが、ダイナミックレンジを格納できるOpenEXRならでは利点で0-255をプラスにもマイナスにも超えて格納してしまいます。


たとえば、上記のように、 といった感じで、8bitのRGBはNuke上では0-1でなのですが、それに縛られない数値になっていることが確認できます。Pworldではそれを利用して、RGB = XYZ として位置情報が格納されています。

それを用いて、カメラ位置を "C" としPworldを "P" とし 視線ベクトルを "E" とすると

E = normalize( P - C )

で求めることができます。
"normalize" というのは、ベクトルの長さを "1" にするという処理です。
この後法線ベクトル(Nworld)を用いて反射ベクトルを求めるために必須事項です。乱暴な解釈ですが、諸々ベクトルの長さを "1" で計算してやれば、結果、反射ベクトルの長さが一定になり、さらに、そうすると、任意のピクセルでの反射ベクトルはその一定の長さを半径としたの「球面」上のドコカシロに終点があることになり、球面マッピングの手法でReflectionが求められます。間違ってたらごめんなさい・・・

で、じゃあ、肝心のどうやってそれをNuke上で表現するかですが・・・

RGBの計算を行えるように一旦カメラ位置 "C" をExpressionNodeを用いてRGBに格納します。
Expressionを用いれば、数式はある程度まとめて、NodeOperatorの数を減らすことができるのですが、今回はわかりやすさを目指して、まわりくどく細かくNodeにわけていくことにします。
で、カメラノードの名前がcamera1として、

C = (Cx,Cy,Cz) = ((Camera1.translate.x),(Camera1.translate.y),(Camera1.translate.z))

として、これをRGBに格納します。



こんな感じで。ExpressionNodeを用いています。

で、さらに、MergeExpressionNodeを用いて、"P - C" を求めます。MergeExpressionNodeを用いると2個のインプットに対してRGBの計算を各ピクセルで行うことができます。

MergeExpressionでrgbで計算をするため、一旦Pworldをrgbに変換します。

P - C = (Px,Py,Pz) - (Cx,Cy,Cz) = ( ( Px - Cx ) , ( Py - Cy ) , ( Pz - Cz ) )

となり、Nuke上ではx,y,zをR,G,Bとして扱っており、さらに、MergeExpressionではinputがAとBとあり、それぞれのベクトルは (Ar,Ag,Ab)、(Br,Bg,Bb) であらわされます。
なので、inputAをPworld、inputBをカメラ位置 "C"とすると、MergeExpression上で

P - C = ( ( Ar - Br ) , ( Ag - Bg ) , ( Ab - Bb ) )

で示せて、実際には





さらに上で求められた、"P - C" のベクトルの長さ(length)を

length = sqrt( (P - C)x*(P - C)x + (P - C)y*(P - C)y + (P - C)y*(P - C)y )

で求めます。長さはベクトルの各成分(x,y,z)の2乗の和の平方根( √ = sqrt( ) )ですので、上の式がそれそのものです。 これをExpressionNodeに落とし込むと、

length = sqrt((r*r)+(g*g)+(b*b))

となり、視線ベクトル "E" は、"P - C" の各成分を、上記で求めた自身の長さ "length" で割ったものなので、

E = normalize( P - C ) = ( r/length , g/length , b/length, ) となり、



となり、長さ "1" のベクトルである視線ベクトル "E" が求められます。

この 長さを "1" にすることを "normalize" と呼んだり、正規化と呼んだりするようです。
ちなみに、RGB値の(この場合ベクトルでのxyzの)四足混合の一つずつだけなら、ExpressionNodeを使わずにMergeNodeの "add" "minus" "multiply" "divide" でも出来ます。順序はA operation Bのようです。minusなら A-Bの順序で組むことが可能です。

さらに、視線ベクトル "E" から反射ベクトル(反射角)を求めます。ここで、反射ベクトルを "R" 、法線ベクトル(Nworld)を "N" とし、反射ベクトル "R" はベクトルの内積を用いて次の公式で与えられます。

R = E - ( 2*(E.N)*N )

"E.N" は、視線ベクトル "E" と 法線ベクトル "N"の内積です。
内積の公式をもちいて、

E.N = (Ex*Nx)+(Ey*Ny)+(Ez*Nz)

とあらわすことができます。
さらに、これをMergeExpressionNodeに落とし込みます。どちらでも結果は同じですが、inputAを視線ベクトル "E" 、inputBを法線ベクトル "N とすると、

E.N = (Ar*Br)+(Ag*Bg)+(Ab*Bb)

であわらすことができ 、都合がいいように実際にShuffleNodeでNworldをRGBに変換しておき、MergeExpressionNodeを用いて・・・



こんな感じです。で、ひとまず

R = E - ( 2*(E.N)*N )

の残り部分 " 2*(E.N)*N " 部分までを求めてみます。MergeExpressionNodeを用いて、以下のようになります。



こんな感じで、さらに

R = E - ( 2*(E.N)*N )

の残り部分、上記で求めたものを視線ベクトル "E"から引きます。
MergeExpressionNodeを用いてもできますし、mergeのoperationを"minus"でもできます。



と、結果、これが、反射ベクトル "R" となります。


ココまで説明してきたように、MergeExpressionNodeは二つのNodeに対応しており、その二つのNode(AとB)に対して計算式を与えることができます。

で、先にも説明したように、画像上のどこのピクセルをとっても、この反射ベクトルの長さは一定なので、環境を「球面」とみなして、環境反射は反射ベクトルをもって、その球面上のある点を指定できます。実際には、計算などが扱い易いように、反射ベクトルも正規化しておきます。そうすることによって、球面上では任意の点[x,y,z]を、次の式を用いて、緯度経度座標[theata phi]に置き換えることができます。

theta = acos(-R.y)
phi = atan2(R.z,R.x) + PI

北緯○○度 東経○○度を思い浮かべてもらえばわかりやすいかもです。
ベクトルを、球体の中心からみて、それらの赤道方向の角度と北極南極を結ぶ線上をあらわす角度で表しています。

ここでのR.x、R.y、R.zは反射ベクトル "R" のそれぞれ x、y、z成分を指してます。PIは円周率です。
今までと同様にExpressionNodeでこれを表わすと



こんな感じです。

さらに、この球体(環境)の座標をuv座標(column(列)とrow(行))で考えて、0-1の範囲で表すと、
赤道方向(phi)は360度分の何度か、北極南極を結ぶ線上(theta)は180度分の何度かであらわせるので、

u = phi / (2*PI)
v = theta / PI

となりますので、




こんな感じです。

で反射ベクトルから環境を参照するためのuv座標を得ることができたので、それとSTMapNodeと環境用のマッピング画像を用いて




こんな感じで、Reflection MappingをNukeで実装できます。
ちなみに、STMapNodeはuv座標から指定したマップ(ここでは環境マップ)をルックアップしてやるためのNodeです。たとえば、


この点は r,g 成分は(0.31323 , 0.57227 )なので、マップからuv座標(column(列)とrow(行))値の(0.31323 , 0.57227 )を参照してきます。


こんな感じです。

入射角に対して、反射角の評価の仕方などを法線とあらかじめ用意したUVなどをくみあわせて、うまくいじってやれば、異方向性反射なども実装できると思います。
今回は環境マッピングでしたが、考え方はshadingにちかいので、NukeではPhong shaderしかありませんが、いろいろとカスタマイズすることも可能です。

もう少し続きますが、今回はココまで。

2010-05-31

Relightingを考察してみる

チラオカ的にRelightingについて考えてみました。
その名前からして Re+Lighting = 再びライティングをする 的なことなのでしょうが、最近もてはやされているRelightingはそれにとどまらないように見受けられます。
Relighting Systemとしては、まだ市販の製品がなく(?)インハウスや、コンポジットでその仕組みを取り入れるというのが実情のようです。
しかし、そんな状況で場末のボクのようなペーペーの耳にも届く情報がちらほらとあり、一つはSPIのインハウスツールであった「Katana」。そしてもう一つは「Bakery Relight」です。Katanaに関しては、FMX 2010でFoundryから、少し発表があったようです。といってもNukeへの組み込みされたものではなく、SPIから買い取ったマンマのものでのデモがあったようです。その内容によると、確かに言葉のマンマ、Relightingツールではあるものの、それにとどまらないといった感じです。Bakery Relightに関しては、http://www.thebakeryanimation.com/に少し情報がありますが、こちらも、ただRelightingをするツールというわけではなく、自前レンダラなどが付属していて、もちろんshaderも編集できる といった感じです。海外で働かれている、ますおさんのブログでKatanaBakery Relightも紹介されています。無断リンクごめんなさい・・・

最近よく耳にするRelighingツールというのは、ボクが思うに、LookDevの作業をそこそこカバーするツールなんだろうなぁ・・・ と考えています。
あと、Hairが扱えるかどうかの差が結構デカイ気もします・・・ 


まともなRelightingシステムを触ってみたいぞ!

IBL+Blurry Reflection

IBL+Blurry Reflection をNukeでやってみました。少し標準のRelightingも足してます。



用いているレンダーパスは、beauty pass以外にPworld、Nworld、BentNormal、ambocc、relfoccです。
BentNormalに関しては、 http://en.wikipedia.org/wiki/Ambient_occlusion ココに少し載っています。
Nuke側で特にaddonするプラグインのようなものは使わずに、標準機能のみでやっております。
これで、shadowを落とせればかなり満足なのですが・・・


LookDev的にはNukeはナカナカ面白いかもしれません。

2010-05-30

Relighting その1

久々の更新・・・
Nukeを用いたRelightingに関して少し紹介しようと。ただ、どう考えてもそこそこなボリュームになるので、何回かに分けます。

実はNukeでのRelightingは実にいろいろな方法があります。
一番ストレートなのはFBXやOBJでジオメトリをインポートして、実際にライティングを施す方法。
Nukeはそこそこハイポリなジオメトリを持ち込んでも、かなり軽快にオペレーションできるので、この手法でもなかなかストレスなく結果に近づけていくことができます。
ただ、デフォームアニメーションしているジオメトリなどは、連番のジオメトリファイルで入ってくるので、やはり毎フレームの読み込みや、また、3Dアプリケーション側での吐き出しなどに時間がかかるだとか、shaderレベルでデフォーム(ディスプレイスメントマッピングなど)しており、3Dアプリケーション側から簡単にはけないだとか・・・ 色々と問題があったりします(どこぞのコンポジットのようにRIBが読めるかは別で・・・)。

で、そうすると、画像を元にRelightingをしたいと思うわけで、そうすると、一番手っ取り早いのが、標準のReLightNodeを用いる方法です。
 ただ、少々面倒なのは、すっーと、ReLightNodeを呼び出すことはなぜかできません・・・
手順としては、NodeOperator > Other(etcのアイコン) > All Plugins > Update
をすることで、アクセスできるようになります。


一旦これをやっておくと、すべてのNodeOperatorがアルファベット順でずらずらと出てきます。この中のReLightNodeです。


ReLightNodeには「color」と「lights」がコネクトできます。ただしこれだけでは不足で、適当に、「Color」と「Lights」をつないでみると・・・ 


なにやら新たにコネクト出来そうなものがでてきて・・・ さらにこいつを引っ張ってみると「camera」がコネクト出来ることがわかります。


実際に「Camera」をコネクトするとさらに、「material」がコネクト出来ます。「material」には 3D > Shader > Phong をとりあえず当てておきます。これで、一応、準備は完了です。


と、大雑把な流れは異常なのですが、ReLightNodeのプロパティーを「normal vectors(Nworld)」と「point positions(Pworld)」が必要なことがわかります(最後に説明します)。


さらに、cameraデータが必要です。3Dアプリケーションなどから、実際にFBXなどでcameraを受け取ることもできるのですが、せっかくなので、すべて画像ベースで行おうとおもいます。ただし、レンダラがVrayに限られます。

vrayCameraAttributes
http://fullblownimages.servebeer.com//scripts.html

というのを利用します。これはプラグインとかではなく、Vrayでレンダリングするとメタデータとして画像に付属している、cameraデータを読み込むツールというか手法です。
中身はただのPythonを用いたExpressionなのですが、RIBなどを編集するのにも用いられる、Python CGkit というものを利用します。

Python Computer Graphics Kit
http://sourceforge.net/projects/cgkit/files/cgkit/
(Python2.6が必須です)

インストールなどの詳しい手法は、各サイトを参考にしてみてください。

でこれらを用いるとカメラの位置、回転、レンズ、アパチャーなど諸々情報が得ることができます。
これでcameraはNukeにインポートできます。もちろん、先に書いたように、FBXで持ち込んでもいけますし、 http://www.creativecrash.com/ などに各3Dアプリケーションに対応した、スクリプトやプラグインなどでNukeへのエクスポーターがいくつか存在していますので、それを使ってもいけるとおもいます。


で、ジオメトリを実際に持ち込んでいれば、ライトを3Dビューで見ながら調整してやれば、感覚が掴みやすいのですが、今回は画像のみで行うということにこだわりたいと思います。
じゃあ、どうするか・・・ PointCloud を用います。PointCloudNodeを用いると、Pwolrd(Ppass)から、Nuke内でPointCloudを構築できます。これにより、いちいちジオメトリをインポートしなくても、Relightingに必要なぐらいの形状は把握することができ、なかなか便利に作業が行えます。
ただ、PointCloudNodeは標準ではありません。ここでは、

PointCloud
http://www.pxfactory.eu/plug/PointCloud/pointCloud.html 

のものを使っております。



説明がボロボロと前後していますが、ここで紹介している手法はかなり「複合技」です。確かに、ReLightNodeにペコっと繋げばいいだけなのですが、しかし、色々と説明しておかなければならない、事項があったりします・・・ その中にPworld(Ppass)と、Nwolrd(Npass)とがあります。Pworldというのは、画像内のピクセルが、3D空間上のどこにあるかの座標を格納しています。XYZの各座標値をRGBの各チャンネルに格納しています。 Nwolrdというのは、同じように、画像に映っているジオメトリの法線情報をRGBの各チャンネルに格納しています。ともに、ワールドスペースだからworldとついてます。他にオブジェクトスペース、カメラスペースなどがあります。


通常CGに用いられてきた8bit画像では、RGBは0-255で格納されておりますが、16bitや32bitの画像フォーマットを用いると、これらを超えた領域でも保存することが可能です。マイナス値も格納されます。で、いろんなレンダパスをAOVとして一枚の画像に保存できるのが、OpenEXRです。memlogのコマツさんも紹介されています。

memlog
OpenEXR使おうぜ

でこれらの複合技でRelightingするとこんな感じ


とはいえ、これで、ライティング調整、質感調整ができるはずもなく、環境マッピングなどを組み合わせて、その後も色々と行うのですが。今回はここまでで。

オマケ
3dsmaxからいろんなものを出す場合は、3dsmaxの座標系とNukeの座標系の違いのため(というか3dsmaxが特殊な座標系)、変換してやる必要があります。PpassもNpassもしかり、今回exrから取り出したcameraデータしかり・・・
簡単に説明すると、XYZ(RGB)でYとZを交換して新たにZになった値にマイナスを掛けると3dsmaxの座標系のZupが通常の座標系Yupに変換できます。
VrayからPython CGkitをつかって取り出したcameraの位置のXYZ、回転のXYZも同様です。

2010-04-08

Nuke on Linux

Twitterでフォローさせてもらってる人が、「Linuxの方が早い」と仰っていたので、
早速試してみました。

AOVのEXRの連番です。1枚38MB程度です。
この素材をローカルにおいて、30枚程度tgaに書き出しました。
どれも、同じローカルのドライブから読んで、同じローカルのドライブに返しています。
すべてSATA接続の7200rpmの単発ディスクです。

XP64(xeon 8コア mem16GB)              2:48(マシンA)
XP64(corei7 仮想8コア mem8GB)      1:48(マシンB)
XP64(corei7 仮想8コア mem8GB)      3:38(マシンC) ←追加
Fedora(corei7 仮想8コア mem8GB)    2:55(マシンC)
centOS(corei7 仮想8コア mem8GB)    2:45(マシンC)

なぜか、XP64(corei7 仮想8コア mem8GB)が一番早い結果に・・・
FedoraとcentOSは全く同環境です。その他も、そんなに大差はありません。
ちなみにどれもCPUは全く使い切らず。

これならwindowsでもいいかなぁと思っております。

追加・・・

追加でLinuxのマシンでxp64で試してみました・・・
そしたら 3:38(遅っ)
どうやらマシンスペックが違うみたいです・・・ うーん、ほとんど一緒のはずなんですが。

ということで、Linuxの方が早いです。

今回、Linuxを作業用のマシンとしてセットアップするに困ったのは、
CentOSでグラフィックカードのドライバがナカナカ入らなかったこと。
kernelやらその辺をいじる必要があったことです。
あと、未だにタブレットのドライバが入らない・・・
Fedoraはその辺がほんの少しだけ簡単にいけました。
グラフィックカードもタブレットもドライバ入れて無くても一応認識はしていて。

あと、selinuxを無効もしくはtargetなどで細かく設定してやら無いとNukeが立ち上がりません。ライセンスサーバーはWindowsでフローティングで取得できてます。.licファイルがデフォルトのまんまだとマシン名になっていて、ネームのナンテロが・・・ みたいなので通らない場合があるかもですが、IPアドレスに書き換えれば問題ありませんでした。pingで確認してみて通れば問題ないと思います。

さらに、追加
AECS4で同様のことをしてみました。環境はマシンA
なんと、 1:23 www

AEの方が断然早いですw

2010-03-26

OpenEXRについて

AOVを使うために必要なEXRですが、コマツさんのブログサイト、memlogで紹介されています。
http://bit.ly/9koEj6

また、twitter上で16bit、32bitについて話していた内容を、新井さん(velvetfaceさん)がまとめられてます。→http://togetter.com/li/10556

追加:
あああ!  Cameradata from EXR ってもしかしたら・・・ Position、Rotation、FOVをRGBに置き換えてどこかに乗っけてんるのか?
調べてみます!
もしそうなら、昨日思いついたことはもう既に、利用されてたってことか・・・ やっぱり、みんなすごいなぁ~