"""
タイトル: プリンシプルBSDFマテリアルプロパティのランダムアニメーションスクリプト
説明:
このスクリプトはBlender内のオブジェクトに適用されるプリンシプルBSDFマテリアルの
すべての主要プロパティをランダムにアニメーション化します。
色、メタリック、ラフネス、トランスミッションなどのプロパティが、
指定したフレーム間隔と範囲内で変化します。
作成日時: 2024年11月17日
バージョン: 1.1.0
"""
import bpy
import random
def create_fully_controllable_material(
name, base_color=(1.0, 1.0, 1.0, 1.0), metallic=0.0, roughness=0.5, ior=1.45, alpha=1.0,
transmission=0.0, subsurface=0.0, specular_ior=0.5, specular_tint=(1.0, 1.0, 1.0, 1.0),
anisotropic=0.0, anisotropic_rotation=0.0, coat_weight=0.0, coat_roughness=0.03, coat_ior=1.5,
sheen_weight=0.0, sheen_roughness=0.5, emission_color=(0.0, 0.0, 0.0, 1.0), emission_strength=0.0,
normal_map=None
):
"""
任意のプロパティを設定可能なプリンシプルBSDFマテリアルを作成します。
"""
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
bsdf_node = nodes.get("Principled BSDF")
if bsdf_node:
bsdf_node.inputs["Base Color"].default_value = base_color
bsdf_node.inputs["Metallic"].default_value = metallic
bsdf_node.inputs["Roughness"].default_value = roughness
bsdf_node.inputs["IOR"].default_value = ior
bsdf_node.inputs["Alpha"].default_value = alpha
if "Transmission" in bsdf_node.inputs:
bsdf_node.inputs["Transmission"].default_value = transmission
if "Subsurface" in bsdf_node.inputs:
bsdf_node.inputs["Subsurface"].default_value = subsurface
if "IOR Level" in bsdf_node.inputs:
bsdf_node.inputs["IOR Level"].default_value = specular_ior
if "Tint" in bsdf_node.inputs:
bsdf_node.inputs["Tint"].default_value = specular_tint
if "Anisotropic" in bsdf_node.inputs:
bsdf_node.inputs["Anisotropic"].default_value = anisotropic
if "Anisotropic Rotation" in bsdf_node.inputs:
bsdf_node.inputs["Anisotropic Rotation"].default_value = anisotropic_rotation
if "Coat" in bsdf_node.inputs:
bsdf_node.inputs["Coat"].default_value = coat_weight
if "Coat Roughness" in bsdf_node.inputs:
bsdf_node.inputs["Coat Roughness"].default_value = coat_roughness
if "Coat IOR" in bsdf_node.inputs:
bsdf_node.inputs["Coat IOR"].default_value = coat_ior
if "Sheen" in bsdf_node.inputs:
bsdf_node.inputs["Sheen"].default_value = sheen_weight
if "Sheen Roughness" in bsdf_node.inputs:
bsdf_node.inputs["Sheen Roughness"].default_value = sheen_roughness
if "Emission Color" in bsdf_node.inputs:
bsdf_node.inputs["Emission Color"].default_value = emission_color
if "Emission Strength" in bsdf_node.inputs:
bsdf_node.inputs["Emission Strength"].default_value = emission_strength
if normal_map and "Normal" in bsdf_node.inputs:
bsdf_node.inputs["Normal"].default_value = normal_map
return mat
def animate_material_properties(
mat, frame_start, frame_end, frame_interval,
base_color_range=((0, 1), (0, 1), (0, 1), (1, 1)),
metallic_range=(0.0, 1.0),
roughness_range=(0.0, 1.0),
transmission_range=(0.0, 1.0),
ior_range=(1.0, 2.0),
alpha_range=(0.0, 1.0),
subsurface_range=(0.0, 1.0),
specular_ior_range=(0.0, 1.0),
anisotropic_range=(0.0, 1.0),
anisotropic_rotation_range=(0.0, 1.0),
coat_weight_range=(0.0, 1.0),
coat_roughness_range=(0.0, 1.0),
sheen_weight_range=(0.0, 1.0),
sheen_roughness_range=(0.0, 1.0),
emission_strength_range=(0.0, 10.0)
):
"""
マテリアルの各プロパティをランダムにアニメーション化します。
Args:
mat (bpy.types.Material): アニメーション対象のマテリアル。
frame_start (int): アニメーション開始フレーム。
frame_end (int): アニメーション終了フレーム。
frame_interval (int): プロパティ変更の間隔。
各プロパティの*_range (tuple): 値の範囲 (min, max)。
"""
nodes = mat.node_tree.nodes
bsdf_node = nodes.get("Principled BSDF")
if not bsdf_node:
print("Error: 'Principled BSDF' node not found in the material.")
return
for frame in range(frame_start, frame_end + 1, frame_interval):
base_color = (
random.uniform(*base_color_range[0]),
random.uniform(*base_color_range[1]),
random.uniform(*base_color_range[2]),
random.uniform(*base_color_range[3])
)
metallic = random.uniform(*metallic_range)
roughness = random.uniform(*roughness_range)
transmission = random.uniform(*transmission_range)
ior = random.uniform(*ior_range)
alpha = random.uniform(*alpha_range)
subsurface = random.uniform(*subsurface_range)
specular_ior = random.uniform(*specular_ior_range)
anisotropic = random.uniform(*anisotropic_range)
anisotropic_rotation = random.uniform(*anisotropic_rotation_range)
coat_weight = random.uniform(*coat_weight_range)
coat_roughness = random.uniform(*coat_roughness_range)
sheen_weight = random.uniform(*sheen_weight_range)
sheen_roughness = random.uniform(*sheen_roughness_range)
emission_strength = random.uniform(*emission_strength_range)
bsdf_node.inputs["Base Color"].default_value = base_color
bsdf_node.inputs["Base Color"].keyframe_insert(data_path="default_value", frame=frame)
bsdf_node.inputs["Metallic"].default_value = metallic
bsdf_node.inputs["Metallic"].keyframe_insert(data_path="default_value", frame=frame)
bsdf_node.inputs["Roughness"].default_value = roughness
bsdf_node.inputs["Roughness"].keyframe_insert(data_path="default_value", frame=frame)
if "Transmission" in bsdf_node.inputs:
bsdf_node.inputs["Transmission"].default_value = transmission
bsdf_node.inputs["Transmission"].keyframe_insert(data_path="default_value", frame=frame)
bsdf_node.inputs["IOR"].default_value = ior
bsdf_node.inputs["IOR"].keyframe_insert(data_path="default_value", frame=frame)
bsdf_node.inputs["Alpha"].default_value = alpha
bsdf_node.inputs["Alpha"].keyframe_insert(data_path="default_value", frame=frame)
if "Subsurface" in bsdf_node.inputs:
bsdf_node.inputs["Subsurface"].default_value = subsurface
bsdf_node.inputs["Subsurface"].keyframe_insert(data_path="default_value", frame=frame)
if "IOR Level" in bsdf_node.inputs:
bsdf_node.inputs["IOR Level"].default_value = specular_ior
bsdf_node.inputs["IOR Level"].keyframe_insert(data_path="default_value", frame=frame)
if "Anisotropic" in bsdf_node.inputs:
bsdf_node.inputs["Anisotropic"].default_value = anisotropic
bsdf_node.inputs["Anisotropic"].keyframe_insert(data_path="default_value", frame=frame)
if "Anisotropic Rotation" in bsdf_node.inputs:
bsdf_node.inputs["Anisotropic Rotation"].default_value = anisotropic_rotation
bsdf_node.inputs["Anisotropic Rotation"].keyframe_insert(data_path="default_value", frame=frame)
if "Coat" in bsdf_node.inputs:
bsdf_node.inputs["Coat"].default_value = coat_weight
bsdf_node.inputs["Coat"].keyframe_insert(data_path="default_value", frame=frame)
if "Coat Roughness" in bsdf_node.inputs:
bsdf_node.inputs["Coat Roughness"].default_value = coat_roughness
bsdf_node.inputs["Coat Roughness"].keyframe_insert(data_path="default_value", frame=frame)
if "Sheen" in bsdf_node.inputs:
bsdf_node.inputs["Sheen"].default_value = sheen_weight
bsdf_node.inputs["Sheen"].keyframe_insert(data_path="default_value", frame=frame)
if "Sheen Roughness" in bsdf_node.inputs:
bsdf_node.inputs["Sheen Roughness"].default_value = sheen_roughness
bsdf_node.inputs["Sheen Roughness"].keyframe_insert(data_path="default_value", frame=frame)
if "Emission Strength" in bsdf_node.inputs:
bsdf_node.inputs["Emission Strength"].default_value = emission_strength
bsdf_node.inputs["Emission Strength"].keyframe_insert(data_path="default_value", frame=frame)
def main():
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
for mat in bpy.data.materials:
bpy.data.materials.remove(mat, do_unlink=True)
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, 1))
sphere = bpy.context.object
bpy.ops.object.shade_smooth()
mat = create_fully_controllable_material(
name="AnimatedMaterial",
base_color=(1, 0, 0, 1),
metallic=0.5,
roughness=0.5
)
sphere.data.materials.append(mat)
animate_material_properties(
mat, frame_start=1, frame_end=250, frame_interval=30,
base_color_range=((0, 1), (0, 1), (0, 1), (1, 1)),
metallic_range=(0.0, 1.0),
roughness_range=(0.0, 1.0),
transmission_range=(0.0, 1.0),
ior_range=(1.0, 2.0),
alpha_range=(0.0, 1.0),
subsurface_range=(0.0, 1.0),
specular_ior_range=(0.0, 1.0),
anisotropic_range=(0.0, 1.0),
anisotropic_rotation_range=(0.0, 1.0),
coat_weight_range=(0.0, 1.0),
coat_roughness_range=(0.0, 1.0),
sheen_weight_range=(0.0, 1.0),
sheen_roughness_range=(0.0, 1.0),
emission_strength_range=(0.0, 5.0)
)
main()