Blenderのシェーダーでは特定のオブジェクトの座標を取得するノードが用意されていません
似たようなノードに、オブジェクトからの座標を出力するノードはありますが
ターゲットのオブジェクトを回転させてしまうと欲しい動作とは違ってきてしまいます。
Blenderにはドライバという 他のオブジェクトの情報から動的に値を設定する機能があって
ノードの値の入力にもドライバを設定することができるので
面倒な設定を自動化するアドオンを作成してみました
bl_info = {
"name" : "Add location node",
"author" : "Yukimituki",
"description" : "",
"blender" : (2, 80, 0),
"version" : (0, 0, 1),
"location" : "",
"warning" : "",
"category" : "Node"
}
import bpy
class NodeLocationNoePanel(bpy.types.Panel):
bl_idname = "NODE_PT_LocationNode"
bl_space_type = 'NODE_EDITOR'
bl_label = "Add Location Node"
bl_region_type = "UI"
bl_category = "Tool"
def draw(self, context):
material = context.material
if hasattr(material, 'node_tree'):
node_tree = material.node_tree
layout = self.layout
row = layout.row()
row.prop_search(node_tree, "target_name", context.scene, "objects")
row = layout.row()
row.operator("nodetree.locationnode")
class NODE_OT_Locationbnode(bpy.types.Operator):
bl_idname = "nodetree.locationnode"
bl_label = "Add object location node"
def execute(self, context):
node_tree = context.material.node_tree
target_name = node_tree.target_name
# ノードの作成
drive_node = node_tree.nodes.new( 'ShaderNodeCombineXYZ' )
drive_node.name = "LocationNode"
drive_node.label = target_name + ".location"
target_obj = bpy.data.objects[target_name]
for i in range(3):
# ノードの値をドライバで設定
prop = drive_node.inputs[i].driver_add('default_value')
#スクリプトタイプのドライバ
prop.driver.type = 'SCRIPTED'
#ドライバ変数の作成
var = prop.driver.variables.new()
var.name = 'location'
var.type = 'SINGLE_PROP'
# ドライバのターゲットの設定
var.targets[0].id = target_obj
var.targets[0].data_path = 'location[%s]' % i
#式の入力
prop.driver.expression = 'location'
return {'FINISHED'}
classes = (
NodeLocationNoePanel,
NODE_OT_Locationbnode,
)
def register():
bpy.types.NodeTree.target_name = bpy.props.StringProperty(name = "Objact")
#classes
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
del bpy.types.NodeTree.target_name
#classes
for cls in classes:
bpy.utils.unregister_class(cls)
if __name__ == "__main__":
register()
アドオンを有効にするとシェーダーエディターのツールタブに
”Add Location Node” という項目が追加します
Object:の項目で座標を取得したいオブジェクトを選択して
Add object location node のボタンを押すと 目的のオブジェクトの座標を取得するノードが作成されます
例えば冒頭のようにマテリアルのついたオブジェクトと目的のオブジェクトの座標から方向ベクトルを取得して
法線との内積をとれば ライティングのようなことができるようになります
このスクリプト単体では使いどころが少ないかもしれませんが
例えば既存のトゥーンシェーダーマテリアルだと オブジェクトを一緒に頒布することになっているものが
これをうまく利用すれば スクリプトだけで設定できるようになるかもしれません