"""
タイトル: 距離による球体の色変化(比率指定版)
説明:
Blenderシーン内で原点に球体を生成し、ランダムに移動。
球体の色は、原点からの距離に応じて赤から青に変化、
距離と色の変化比率を指定できます。
作成日: 2024年11月17日
バージョン: 1.1.0
"""
import bpy
import random
import math
def create_material_with_color_ratio(name, color1, color2, ratio):
"""
原点からの距離に応じて色を変化させるマテリアルを作成。
Args:
name (str): マテリアル名。
color1 (tuple): 距離が小さいときの色 (R, G, B, A)。
color2 (tuple): 距離が大きいときの色 (R, G, B, A)。
ratio (float): 距離と色の変化の比率。
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")
bsdf_node = nodes.new(type="ShaderNodeBsdfPrincipled")
distance_node = nodes.new(type="ShaderNodeVectorMath")
scale_node = nodes.new(type="ShaderNodeMath")
color_ramp_node = nodes.new(type="ShaderNodeValToRGB")
geometry_node = nodes.new(type="ShaderNodeNewGeometry")
distance_node.operation = 'LENGTH'
scale_node.operation = 'MULTIPLY'
scale_node.inputs[1].default_value = ratio
color_ramp_node.color_ramp.interpolation = 'LINEAR'
color_ramp_node.color_ramp.elements[0].color = color1
color_ramp_node.color_ramp.elements[1].color = color2
links.new(geometry_node.outputs["Position"], distance_node.inputs[0])
links.new(distance_node.outputs["Value"], scale_node.inputs[0])
links.new(scale_node.outputs["Value"], color_ramp_node.inputs["Fac"])
links.new(color_ramp_node.outputs["Color"], bsdf_node.inputs["Base Color"])
links.new(bsdf_node.outputs["BSDF"], output_node.inputs["Surface"])
return mat
def create_moving_sphere(location, material_name, color1, color2, ratio):
"""
球体を作成し、指定したマテリアルを適用します。
Args:
location (tuple): 球体の初期位置。
material_name (str): 使用するマテリアル名。
color1 (tuple): 距離が小さいときの色。
color2 (tuple): 距離が大きいときの色。
ratio (float): 距離と色変化の比率。
Returns:
bpy.types.Object: 作成した球体。
"""
bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=location)
sphere = bpy.context.object
bpy.ops.object.shade_smooth()
mat = create_material_with_color_ratio(material_name, color1, color2, ratio)
sphere.data.materials.append(mat)
return sphere
def animate_sphere_movement(sphere, frame_start, frame_end, frame_interval, move_range):
"""
球体のランダムな動きをアニメーション化します。
Args:
sphere (bpy.types.Object): アニメーション化する球体。
frame_start (int): アニメーションの開始フレーム。
frame_end (int): アニメーションの終了フレーム。
frame_interval (int): フレーム間隔。
move_range (tuple): 移動範囲 (min, max)。
"""
for frame in range(frame_start, frame_end + 1, frame_interval):
bpy.context.scene.frame_set(frame)
new_location = (
random.uniform(*move_range),
random.uniform(*move_range),
random.uniform(*move_range)
)
sphere.location = new_location
sphere.keyframe_insert(data_path="location", 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)
sphere = create_moving_sphere(
location=(0, 0, 0),
material_name="DistanceColorMaterial",
color1=(1.0, 0.0, 0.0, 1.0),
color2=(0.0, 0.0, 1.0, 1.0),
ratio=0.2
)
frame_start = 1
frame_end = 250
frame_interval = 10
move_range = (-5, 5)
animate_sphere_movement(sphere, frame_start, frame_end, frame_interval, move_range)
bpy.context.scene.frame_set(1)
main()