"""
タイトル: マテリアル4色切り替えアニメーションスクリプト
説明:
Blender内でミックスシェーダーを使用して、4種類の色(例: 赤、青、緑、黄色)を順番に切り替える
球体のマテリアル色をアニメーション化するシーンを作成します。
色の切り替え順と間隔はメイン関数で設定可能で、4色以上に拡張する際にも対応可能です。
作成日時: 2024年11月14日
バージョン: 2.1.0
"""
import bpy
import random
def clear_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)
if not any(obj.type == 'CAMERA' for obj in bpy.data.objects):
bpy.ops.object.camera_add(location=(0, -10, 5), rotation=(1.1, 0, 0))
if not any(obj.type == 'LIGHT' for obj in bpy.data.objects):
bpy.ops.object.light_add(type='POINT', location=(5, -5, 10))
def create_mixed_material(name, colors):
"""
任意の4色を切り替えるミックスマテリアルを作成します。
Args:
name (str): マテリアル名。
colors (list): 色リスト [(R, G, B, A), ...]。
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")
mix_shader_3 = nodes.new(type="ShaderNodeMixShader")
diffuse_nodes = []
for i, color in enumerate(colors):
diffuse = nodes.new(type="ShaderNodeBsdfDiffuse")
diffuse.inputs["Color"].default_value = color
diffuse_nodes.append(diffuse)
links.new(diffuse_nodes[0].outputs["BSDF"], mix_shader_1.inputs[1])
links.new(diffuse_nodes[1].outputs["BSDF"], mix_shader_1.inputs[2])
links.new(mix_shader_1.outputs["Shader"], mix_shader_2.inputs[1])
links.new(diffuse_nodes[2].outputs["BSDF"], mix_shader_2.inputs[2])
links.new(mix_shader_2.outputs["Shader"], mix_shader_3.inputs[1])
links.new(diffuse_nodes[3].outputs["BSDF"], mix_shader_3.inputs[2])
links.new(mix_shader_3.outputs["Shader"], output_node.inputs["Surface"])
factor_node_1 = nodes.new(type="ShaderNodeValue")
factor_node_2 = nodes.new(type="ShaderNodeValue")
factor_node_3 = nodes.new(type="ShaderNodeValue")
factor_node_1.outputs[0].default_value = 0.0
factor_node_2.outputs[0].default_value = 0.0
factor_node_3.outputs[0].default_value = 0.0
links.new(factor_node_1.outputs[0], mix_shader_1.inputs["Fac"])
links.new(factor_node_2.outputs[0], mix_shader_2.inputs["Fac"])
links.new(factor_node_3.outputs[0], mix_shader_3.inputs["Fac"])
mat["factor_nodes"] = [factor_node_1.name, factor_node_2.name, factor_node_3.name]
return mat
def animate_mixed_material(mat, frame, color_index):
"""
ミックスマテリアルの色を4色のうち1色に切り替える。
Args:
mat (bpy.types.Material): ミックスマテリアル。
frame (int): 色を切り替えるフレーム。
color_index (int): 切り替える色のインデックス (0: 赤, 1: 青, 2: 緑, 3: 黄)。
"""
factor_nodes = mat.get("factor_nodes")
if not factor_nodes:
print("Factor nodes not found in material.")
return
for i, node_name in enumerate(factor_nodes):
factor_node = mat.node_tree.nodes.get(node_name)
if not factor_node:
print(f"Factor node {node_name} not found.")
continue
factor_value = 1.0 if color_index == i else 0.0
factor_node.outputs[0].default_value = factor_value
factor_node.outputs[0].keyframe_insert(data_path="default_value", frame=frame)
def main():
clear_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"
colors = [
(1.0, 0.0, 0.0, 1.0),
(0.0, 0.0, 1.0, 1.0),
(0.0, 1.0, 0.0, 1.0),
(1.0, 1.0, 0.0, 1.0)
]
mixed_material = create_mixed_material("FourColorMix", colors)
sphere.data.materials.append(mixed_material)
frame_start = 1
frame_interval = 60
total_switches = 8
for i in range(total_switches):
color_index = i % 4
frame = frame_start + i * frame_interval
animate_mixed_material(mixed_material, frame, color_index)
bpy.context.scene.frame_set(1)
main()