2014年10月

2014年10月31日

Geometric Normal Outputの出力がプレビューとレンダリングで異なる modo801

3次元の方向を表すのにXYZの3つの値を使うわけだけど、 長さが1の単位ベクトルで方向を表すならXYZの値はそれぞれ−1〜1の値をとり、常に3つの値の二乗の値を全て足すと1になるように3つの値が変化するわけだ。

この方向を表す単位ベクトルをRGB各8ビットの色空間で表す場合、8ビットは単純に使うと0〜255の整数しか表せないから当然マイナス方向のベクトルが表せなくなってしまう。そこで数値をちょっとオフセットして、0〜127までを負の数値、128を0、129〜255までを正の数値として0を−1、128を0、255を+1にマッピングして−1から+1までの数値を表すことが考えられた。

だからXYZ(0,0,0)ベクトルはRGBで(128,128,128)に置き換えられる。同様にXYZ(0,0,1)はRGB(128,128,255)、XYZ(0,0,−1)はRGB(128,128,0)のように置き換えが可能になる。

これがノーマルマップなどでよく使われる色による方向ベクトルの表し方だ。

だから下のような立方体の法線をUVマップに色でベイクすると、

fig01

このようになる。

fig02

上の面の法線ベクトルはY軸正の向きでXYZ(0,1,0)なのでRGBでは(128,255,128)といった感じだ。

modoのレンダー出力アイテムの「Geometric Normal Output」はこの方式で色を出力するので、シェーダーツリーにこのアイテムを加えて、

fig03

立方体をエフェクトを「Geometric Normal Output」に切り替えたプレビューで確認すると、このように各座標軸の方向を向いている面は前出の画像の色の通りの色で着色される。

fig04

こっちが裏側。

fig06

しかしこれをレンダリングしてみるとこのように明らかに色が異なった結果になってしまう。裏側は真っ黒だ。どうやらこのレンダリングでは0〜255を0〜1にマッピングして、マイナスはクリップしてしまっているようだ。701ではそのまま出たんだけど何か仕様に変更があったのだろうか。

fig07

プレビューとレンダリングで結果が異なるのはちょっと戴けない。

マニュアルを見ると、

The 'Geometric Normal' output simply renders all meshes with a color ramp based on the angle of their polygonal normal, where the RGB image components represent the corresponding XYZ vectors, so values will be negative unless the 'Normalize' option is enabled.

とある。なにか「Normalize」オプションが係わっているような記述なんだけどどこだろうと思っていたらどうやら「Geometric Normal Output」アイテムの「ピクセル値のリマップ」というオプションがそれにあたるらしい。

fig08

これをONにしてレンダリングしたら確かにちゃんと補正がかかった。

fig09

逆に言えばこれをOFFにしてもプレビューが補正しない色でレンダリングされないのがおかしい事になるな。

ちなみに上のレンダリング結果の色は実はちょっとおかしい。これは「出力カラースペース」をちゃんと指定していないからで、「出力カラースペース」を「リニア」にすると、

fig11

このようにやっとちゃんとした色で出力された。メデタシメデタシ。

fig10

確かに近年では実数でRGBを表せるようになってるし、RGB各8ビットの色空間なんて時代の遺物だもんね。下手に128だけずらした数値なんて使ってたら単位ベクトルじゃない大きさのベクトルまで実数のRGBで表す時にめんどうな事になるもんね。RGBが実数値で表現できるならXYZの値をそのままRGBに置き換えるのが素直でいいもんね。今回の変更はそういう流れなのかな?

それではまた来週。

modo801ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG

2014年10月30日

2015の新機能を調べてみた その49 3dsmax 2015

前回に引き続きピクセルシェーダーの「Inside Loop」ソケットに接続されている「InsideLightLoop」ノードの中の「DiffuseMethod」を調べてみたい。

今回は「BlendedNormalDiffuse」から。

fig01

このノードにはヘルプのコメントが付いていて、

ライトがスキャッタリングを起こしているように見せるスキンの拡散ライティング

とある。要するにこれは皮膚のシェーディング用に作られたノードのようだ。

このグループも開くと各パラメータのデフォルト値が設定されている。

fig02

ソケット デフォルト値
Albedo Color グレイ:float3
Soften Diffuse 0.15:float
Soften Diffuse Mask 1.0:float
Geometry Normals World Normal:float3
Light Vector Light Vector:float3
World Normal Map RGB(0.0,0.0,1.0):float3

ソケットから入力が無ければこれらデフォルト値が「Blend Normal Diffuse」ノードに入力される。

そしてこれがその「Blend Normal Diffuse」ノードの中身だ。

fig03

皮膚に入射した光が皮膚の下で内部散乱する時に血液の赤色の影響を受けて赤くなり、その一部が表皮に現れることで影になっている部分にも赤みを帯びた明るさが現れたりする様子を表現出来るよう調整されたグラフのようだ。グラフの最後のところで、赤色と緑&青が分離して処理が行われているようだ。

fig04

まあこれはちょっと置いといて、その前段階として2つのノードグループの役割について調べてみた。名前は違うけど実はこのノードの中身は同じだ。

fig05

これがその中身。

fig06

数式で書くと以下のようになる(入力ソケットは2つのノードで名称が異なっているけどグラフ自体は同じなのでもう一つのノードグループの式は「Red」を「Blue」に読み替えるなど対応するソケット名で置き換えて考えてね)。

(1-Red)(Geometry_Normal・Light_Vector)+Red

法線ベクトルと光線ベクトルの内積「Geometry_Normal・Light_Vector」をそのポイントの乱反射の明るさとするのは前回の「Lambert」モデルでやったよね。上式で「Red」の値が0ならばまさに「Lambert」モデルでの乱反射の明るさになり、「Red」の値が1ならば式の値は定数の1になり、入射角に関係なく明るさが一定になるってわけだ。

人間の皮膚が内部で光を散乱させて光が直接当ってないところまで明るくなるような状態を表現するのが目的だから、上式で言えば「Red」の値が1に近づくほど陰影が無くなって効果が強くかかるって事なんだろうね。

それではまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)3ds Max | CG

2014年10月29日

modo801の新機能を調べてみた その48 modo801

今回もmodo801の新機能に書いてある新機能について調べてみたい。

今回は「Preview Enhancement: New option to render all available render outputs simultaneously when preview rendering.」についてだ。

modoのレンダリングはレンダー出力アイテムによって出力タイプが決定して、1回のレンダリングで複数タイプのレンダリングが可能だ。

fig03

これらの出力はプレビュービューポートで「エフェクト」メニューで切り替えて表示する事が出来る。

fig04

しかし以前のmodoではこの切り替えのたびにレンダリングがやり直されていた。

fig01

新機能の「レンダー全出力」はプレビューのレンダリング時に全てのレンダー出力を計算してしまうことで切り替えの時は計算済みの画像を切り替えるだけにする機能だ。

fig05

だからレンダー出力を切り替えてもいちいち再レンダリング処理が発生しなくなり、切り替えが素早く快適になるというものだ。

fig02

これはONにしておきたいな。

それではまた次回。

modo801ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG

2014年10月28日

2015の新機能を調べてみた その49 3dsmax 2015

前回に引き続きピクセルシェーダーの「Inside Loop」ソケットに接続されている「InsideLightLoop」ノードを調べてみたい。

前回はライトがアンビエントライトだった時のグラフを調べた。今回はアンビエントライトじゃない時のグラフだ。

fig01

こちら側のグラフの入り口には「Translucency」「DiffuseMethod」「SpeculaMethod」などの名前が見える。

fig02

この中からまず「DiffuseMethod」ノードを見てみたい。ノードを開くとこのように「Lambert」と「BlendedNormal」の切り替え方式になっている。

fig03

「PathDirection」ノードの「Names」ソケットに「String Values」を複数繋ぎ、「Options」にも複数のグラフを繋ぐと、

fig05

「PathDirection」ノードの「Options」プロパティに「String Values」でセットした名前のリストが出るようになって、これを選ぶと「Options」ソケットに接続された対応するグラフが「Result」ソケットに接続される仕組みだ。

fig04

この切り替えでディフューズの色を計算するモデルが切り替え出来るわけだね。まず「Lambert」ノードの方を開いてみるとこのようにディフューズカラー、法線、ライトベクトルのデフォルト値が用意されて、各ソケットに値が未接続でもちゃんと計算が出来るようになっている。計算本体はさらにこの中の「LambertDiffuse」ノードの中みたいだな。

fig06

これがその「LambertDiffuse」ノードの中身。

fig07

入射光のベクトルとサーフェスの法線の内積で明るさを計算して、それにディフューズカラーをかけて乱反射光の色を計算している。前提として光源ベクトルも法線ベクトルも正規化して大きさが1になってないとならない。

fig09

このモデルだとある地点のサーフェスの明るさは法線と光源ベクトルとのなす角θのcosθで計算されることになる。cosθはθが0で最大の1、90度で0になるから光が面に垂直に当たる時に明るさが最大になって、真横から当る時が最小になるわけだ。

ところでこの「DotOp」ノードのヘルプがこうなってるんだけど、

fig08

ちょっと考えちゃうよね。コード化してみるとやはり単に内積を計算しているだけなんだけど、この書き方だとまるでacosまで計算しているように思えちゃう。これはここから出力した値をacosで計算すれば角度が出せるって意味みたいだな。

続きはまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)3ds Max | CG

2014年10月27日

ペアレントしたアイテムが親を動かしても動かない modo801

タイトルを見て、「あーアレ忘れてるだろ」って即答できる人には関係ない話なんだけど、とある事をやるとタイトルにあるような現象が起きる。

これはソフトの重要な機能のひとつであって、バグでも何でもないんだけど、急いでる時にこういう現象が起きると焦っちゃうよね。

modoのツールオプションはmodoを終了しても保存されるものもあれば、リセットされるものもある。今回話題にしているのは設定が保存されるオプションのもので、だからこの事態はmodoを立ち上げなおしても変化しない。まあ最後は設定をリセットすればいいわけだけどね。

で、何が原因かと言うと、トランスフォームツールの「子階層の補正」がONになってることだ。これがONになっていると親レイヤの動きをキャンセルするように子階層が移動するようになるから、親階層を動かしても子がついてこないわけなんだね。

fig01

子階層を動かさないで親階層だけ動かす必要も確かに多いけど、やはり階層にして動かすとなれば親が子に従うのがデフォルトだろうし、このへんは起動時にリセットしてくれるとありがたいね。

例えばMODO801.CFGファイルの中にスタートアップスクリプトを起動する記述を(<configuration>〜</configuration>のレベルに)加えて、

<atom type="StartupCommands">
<list type="Command">@startup.py</list>
</atom>

起動するスクリプトstartup.pyを作ってmodoのスクリプトのパスが通ったフォルダに入れるか上記のファイル名のところにフルパスを書いてやれば、

#python
lx.eval('select.type item')
lx.eval('tool.set TransformMove on')
lx.eval('tool.attr xfrm.transform comp false')
lx.eval('tool.set TransformMove off')
seltype = lx.eval('pref.value application.initialSelType ?')
lx.eval('select.type vertexselect.type %s' % seltype)

起動した時に「子階層の補正」は自動的にOFFになる。

それではまた次回。

modo801ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)TrackBack(0)modo | CG
Archives