"""
タイトル: RGB比率コントロール可能なマテリアルアニメーションスクリプト
説明:
Blender内でR(赤)、G(緑)、B(青)の3色を使用し、
それぞれの割合をミックスシェーダーでコントロール可能なマテリアルを作成します。
色の切り替えと比率の変更はアニメーションとして設定されます。
作成日時: 2024年11月14日
バージョン: 1.0.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_mixed_material(name):
"""
R, G, Bの3色をミックスするマテリアルを作成します。
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")
mix_shader_1 = nodes.new(type="ShaderNodeMixShader")
mix_shader_2 = nodes.new(type="ShaderNodeMixShader")
diffuse_r = nodes.new(type="ShaderNodeBsdfDiffuse")
diffuse_g = nodes.new(type="ShaderNodeBsdfDiffuse")
diffuse_b = nodes.new(type="ShaderNodeBsdfDiffuse")
diffuse_r.inputs["Color"].default_value = (1.0, 0.0, 0.0, 1.0)
diffuse_g.inputs["Color"].default_value = (0.0, 1.0, 0.0, 1.0)
diffuse_b.inputs["Color"].default_value = (0.0, 0.0, 1.0, 1.0)
links.new(diffuse_r.outputs["BSDF"], mix_shader_1.inputs[1])
links.new(diffuse_g.outputs["BSDF"], mix_shader_1.inputs[2])
links.new(mix_shader_1.outputs["Shader"], mix_shader_2.inputs[1])
links.new(diffuse_b.outputs["BSDF"], mix_shader_2.inputs[2])
links.new(mix_shader_2.outputs["Shader"], output_node.inputs["Surface"])
factor_node_1 = nodes.new(type="ShaderNodeValue")
factor_node_2 = nodes.new(type="ShaderNodeValue")
factor_node_1.outputs[0].default_value = 0.5
factor_node_2.outputs[0].default_value = 0.5
links.new(factor_node_1.outputs[0], mix_shader_1.inputs["Fac"])
links.new(factor_node_2.outputs[0], mix_shader_2.inputs["Fac"])
mat["factor_nodes"] = {
"Mix1": factor_node_1.name,
"Mix2": factor_node_2.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), ...]。
"""
factor_nodes = mat.get("factor_nodes")
if not factor_nodes:
print("Factor nodes not found in material.")
return
factor_node_1 = mat.node_tree.nodes.get(factor_nodes["Mix1"])
factor_node_2 = mat.node_tree.nodes.get(factor_nodes["Mix2"])
if not factor_node_1 or not factor_node_2:
print("Factor nodes not found in material nodes.")
return
frame = frame_start
for color_ratio in color_sequence:
r, g, b = color_ratio
factor_node_1.outputs[0].default_value = r / (r + g) if (r + g) != 0 else 0.5
factor_node_2.outputs[0].default_value = (r + g) / (r + g + b) if (r + g + b) != 0 else 0.5
factor_node_1.outputs[0].keyframe_insert(data_path="default_value", frame=frame)
factor_node_2.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_mixed_material("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()