2008年6月1日日曜日

blender - PythonのNode実験(2)

マテリアルノードでトゥーンシェーディングをやるとして、
従来のやり方だと、マテリアル毎にいちいちNodeEditorかCol Rampを開いて、色の調整をしないといけなかった。

マテリアル数が増えてくると、これは非常にメンドクサイ。
マテリアル色と別に、シェーディング用の色を設定しないといけないので、手間が2倍だ。

また、DirectXで使うことを考えると、ノードのエクスポートは若干面倒なので、もっと楽に扱えて、エクスポーターもノードをエクスポートせずに何とかする方法を考えたい。

つまり
・2色を閾値で区切る or 2色のグラデーションでOK
・一度設定したらノードエディタを開かず、全てマテリアルパネルから操作できるように
・色はマテリアル色や頂点カラーから流用

くらいが出来れば良しとしよう。

よろしい、ならばPyNodeだ。

とりあえずライトのベクトルの取得法が良く分からないので、正面にライトがあることにする。
また、とりあえずは、閾値で区切るスイッチ動作だけとする。


from Blender import Node
from Blender.Mathutils import *

class ToonColorNode(Node.Scripted):
def __init__(self, sockets):
out = Node.Socket('Color', val = 4 * [1.0])
color1 = Node.Socket('Color1', val = 4 * [1.0])
color2 = Node.Socket('Color2', val = 4 * [1.0])
weight = Node.Socket('weight', val = 0.5)
sockets.i = [color1, color2, weight]
sockets.o = [out]

def __call__(self):
color1 = self.i['Color1']
color2 = self.i['Color2']
weight = self.i['weight'] * 100

vec1 = Vector(self.shi.surfaceViewVector)
vec2 = Vector(self.shi.viewNormal)
vangle = AngleBetweenVecs(vec2, vec1)

if vangle > weight:
self.o['Color'] = color1
else:
self.o['Color'] = color2

__node__ = ToonColorNode


これをDynamicに読込む。

また、ノード内にマテリアルを2つ設定し、
1つめ(Link and Pipelineの上のほう)はshadelessなVColPaint(頂点カラー)に設定
2つめ(Link and Pipelineの下のほう)はshadelessだけ(=マテリアルカラー)に設定する。
また、2つめのほうは、alphaを閾値として使う。

すると、以下のような感じになる。



色と閾値をマテリアルパネルから操作できて(*)、エクスポート時にノードをエクスポートしなくても閾値含めてエクスポートできる。

(*) 1つめのマテリアルは頂点カラーなので、NodeEditorで切り替えなくても、VertexPaintで色を変えられる。まぁこれはこれで面倒かもー。



・・・・で、ライトベクトルってどうやって取得するんだろう?orz

0 件のコメント: