"""
タイトル: RGB比率コントロール可能なマテリアルアニメーションスクリプト(Combine XYZ 使用版)
説明:
Diffuse BSDFの「Color」入力にCombine XYZノードを接続し、ValueノードでRGBそれぞれの比率をコントロールします。
アニメーションで色比率を動的に変更することが可能です。
作成日時: 2024年11月14日
バージョン: 1.1.0
"""
import bpy
def setup_scene():
"""カメラとライト、既存のオブジェクトを初期化"""
for obj in bpy.data.objects:
bpy.data.objects.remove(obj, do_unlink=True)
for mat in bpy.data.materials:
bpy.data.materials.remove(mat, do_unlink=True)
bpy.ops.object.camera_add(location=(0, -10, 5), rotation=(1.1, 0, 0))
camera = bpy.context.object
camera.name = "Camera"
bpy.ops.object.light_add(type='POINT', location=(5, -5, 10))
light = bpy.context.object
light.name = "Light"
def create_rgb_material_with_combine(name):
"""
Combine XYZを使用してRGB比率をコントロールするマテリアルを作成。
Args:
name (str): マテリアル名。
Returns:
bpy.types.Material: 作成したマテリアル。
"""
mat = bpy.data.materials.get(name)
if mat is None:
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
nodes = mat.node_tree.nodes
links = mat.node_tree.links
for node in nodes:
nodes.remove(node)
output_node = nodes.new(type="ShaderNodeOutputMaterial")
diffuse_node = nodes.new(type="ShaderNodeBsdfDiffuse")
combine_xyz = nodes.new(type="ShaderNodeCombineXYZ")
value_r = nodes.new(type="ShaderNodeValue")
value_g = nodes.new(type="ShaderNodeValue")
value_b = nodes.new(type="ShaderNodeValue")
value_r.outputs[0].default_value = 1.0
value_g.outputs[0].default_value = 0.0
value_b.outputs[0].default_value = 0.0
links.new(value_r.outputs[0], combine_xyz.inputs[0])
links.new(value_g.outputs[0], combine_xyz.inputs[1])
links.new(value_b.outputs[0], combine_xyz.inputs[2])
links.new(combine_xyz.outputs[0], diffuse_node.inputs["Color"])
links.new(diffuse_node.outputs["BSDF"], output_node.inputs["Surface"])
mat["value_nodes"] = {
"R": value_r.name,
"G": value_g.name,
"B": value_b.name,
}
return mat
def animate_rgb_material(mat, frame_start, frame_interval, color_sequence):
"""
マテリアルのRGB比率をアニメーション化します。
Args:
mat (bpy.types.Material): マテリアル。
frame_start (int): アニメーション開始フレーム。
frame_interval (int): 各切り替え間隔のフレーム数。
color_sequence (list): 色の比率のリスト [(R, G, B), ...]。
"""
value_nodes = mat.get("value_nodes")
if not value_nodes:
print("Value nodes not found in material.")
return
value_r = mat.node_tree.nodes.get(value_nodes["R"])
value_g = mat.node_tree.nodes.get(value_nodes["G"])
value_b = mat.node_tree.nodes.get(value_nodes["B"])
if not value_r or not value_g or not value_b:
print("Value nodes not found in material nodes.")
return
frame = frame_start
for color_ratio in color_sequence:
r, g, b = color_ratio
value_r.outputs[0].default_value = r
value_g.outputs[0].default_value = g
value_b.outputs[0].default_value = b
value_r.outputs[0].keyframe_insert(data_path="default_value", frame=frame)
value_g.outputs[0].keyframe_insert(data_path="default_value", frame=frame)
value_b.outputs[0].keyframe_insert(data_path="default_value", frame=frame)
frame += frame_interval
def main():
setup_scene()
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, 1))
sphere = bpy.context.object
bpy.ops.object.shade_smooth()
sphere.name = "Sphere"
rgb_material = create_rgb_material_with_combine("RGBMaterial")
sphere.data.materials.append(rgb_material)
frame_start = 1
frame_interval = 30
color_sequence = [
(1.0, 0.0, 0.0),
(0.0, 1.0, 0.0),
(0.0, 0.0, 1.0),
(1.0, 1.0, 0.0),
(0.0, 1.0, 1.0),
(1.0, 0.0, 1.0)
]
animate_rgb_material(rgb_material, frame_start, frame_interval, color_sequence)
bpy.context.scene.frame_set(1)
main()