見出し画像

マテリアル・ノードを調べる

マテリアルは、デフォルトではノードを繋げて利用するけど、ノードを繋がなくても利用できる。

ノードを繋がない場合でも色などをつけることができる。これをマテリアル・カラーと呼ぶ人もいるようだ。

マテリアル・カラーは、マテリアル自身が保持しているパラメータによって、フェイスに色をつけたりすることができるようになっている。

まずは、このマテリアル・カラーから調べてみた。

マテリアル・カラーへのアクセス

マテリアル・カラーにアクセスするには、マテリアル・オブジェクトのuse_nodeプロパティをFalseに設定する必要がある。

UIで切り替えてもいいのだけど、折角なのでスクリプトで切り替える。

bpy.data.meshes["Cube"].materials["Material"].use_node = False

マテリアル・カラーはBase Colorプロパティから指定することができる。

スクリプトからのアクセスだと、diffuse_colorプロパティが紐づけられている。

>>> tuple(bpy.data.meshes["Cube"].materials["Material"].diffuse_color)
(0.003980848006904125, 0.8000000715255737, 0.0, 1.0)

マテリアル・カラーを指定すると、いつでもオブジェクトに色がつくようになる。アーティストによっては、このマテリアル・カラーを使ってメッシュ・データの領域を区分し、視覚的に判別できるようにしているらしい。

ノード・ツリー

ノード・ツリーは、ノードを繋げていって、各ノードのパラメータを授受し、最終出力を決めるためのデータ構造になっている。ツリー・ノードを利用するためには、use_nodeプロパティをTrueにする必要がある。

ノードについているポートの形式で大別すると、出力専用のノード、入力専用のノード、入出力可能なノードにわけられる。

出力専用のノードは、たとえばイメージ・テクスチャ・ノードが挙げられる。Blender上ではInputに分類されていて、こちらの区分はポートではなく、データの入出力に着目して命名しているらしい。

マテリアルのノード・ツリーは初期状態だと、次のイメージのようになっている。

ノード・データはマテリアル・オブジェクトのnode_treeプロパティにぶら下がっているnodesプロパティで管理されている。スクリプトで名前を確認してみると、Meterial Outputが先に登録されているのが面白い。

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[0].name
'Material Output'

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[1].name
'Principled BSDF'

新しいノードを追加するには、newメソッドを呼び出せばいいみたい。newメソッドの引数はノードのタイプ名を与える必要がある。

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes.new("ShaderNodeVertexColor")
bpy.data.materials['Material'].node_tree.nodes["Vertex Color"]


シェーダー・ノードの一覧はBlender APIのヘルプに載ってる。bpy.typesにサブクラスとして定義されているので、インタラクティブ・コンソールからbpy.types.ShaderNodeまで叩いてタブ・キーを押せば、簡単に一覧を取得できる。もちろん、Shadingワーク・スペースでポップ・アップを表示させることもできる。

ノードのリンク

ノード・データ同士を繋ぐには、node_treeプロパティのlinks.newメソッドを使う。リンクは、あるノード・データの出力を別のノード・データの入力にするだけなので、操作そのものは難しくない。

試しに先ほど生成したVertex Colorノードの出力をPrincipled BSDFノードにリンクさせる。コネクタ名は辞書形式でアクセスできるので楽だ。

>>> nodeTree = bpy.data.meshes["Cube"].materials["Material"].node_tree
>>> nodes = nodeTree.nodes
>>> nodeTree.links.new(nodes["Vertex Color"].outputs["Color"], nodes["Principled BSDF"].inputs["Base Color"])
bpy.data.materials['Material'].node_tree

グルーピング

ノード・データは、グルーピングすることでプログラミング言語の関数のようにブラックボックス化して利用することができる。

Vertex ColorノードとPrincipled BSDFノードを選択し、AddメニューからGroup→Make Groupを選択するとグループになる。Shadingワーク・スペースの背景色も変わる。

グループ編集モードから抜けるには、右上にある矢印をクリックする。これがちょっとわかりづらい。

グループ編集モードを抜けると、いつものシェーダ・エディタ画面へ戻る。グルーピングされているノードは、Node Groupという名前が与えられている。

このとき、ノード・データがどうなっているのかを調べてみた。グルーピングされているデータは新しいノード・データとして定義されていて、グループに含まれているノード・データは別の場所で管理されるようになっているらしい。

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[1].name
'Group'

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[2].name
Traceback (most recent call last):
 File "<blender_console>", line 1in <module>
IndexError: bpy_prop_collection[index]: index 2 out of range, size 2

グルーピングされたノード・データがどこにあるのかを探してみると、新しく作成されたグループのノード・データの下にあった。ノード・データにはnode_treeプロパティがあり、ネストされる構造になったいた。

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[1].node_tree.nodes[0].name
'Principled BSDF'

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[1].node_tree.nodes[1].name
'Vertex Color'

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[1].node_tree.nodes[2].name
'Group Input'

>>> bpy.data.meshes["Cube"].materials["Material"].node_tree.nodes[1].node_tree.nodes[3].name
'Group Output'

Group InputノードとGroup Outputノードは、関数で言えば引数と戻り値に当たる。

グループ化されたノードをコピーすれば、グループごとコピーされる。ただ、単純なコピーをするだけでは参照が重複してしまうようなので、取り扱いは注意が必要になりそう。

この記事が気に入ったらサポートをしてみませんか?