0

I have a use case where I have to change an object's material color per keyframe (i.e. the color will change instantly between keyframes). I have been able to easily do this for other data (location, rotation) but have been stuck on the color part. I have to do this programmatically through the Python API.

Other answers I looked at: 1 2

I believe I am doing what the answers in those questions suggest, but have not been successful. Here is a minimal example where I want the cube to snap between red and blue colors for 1000 keyframes:

import bpy
import numpy as np

cube = bpy.data.objects["Cube"]

material = bpy.data.materials.new('material') material.use_nodes = True base_color = material.node_tree.nodes["Principled BSDF"].inputs[0] red = [1,0,0,1] blue = [1,0,1,1] base_color.default_value = red color = red

location = np.array([0,0,0]) for i in range(1000): cube.active_material = material bsdf = material.node_tree.nodes['Principled BSDF'] bsdf.inputs['Base Color'].keyframe_insert(data_path="default_value", frame=i) cube.location = location cube.keyframe_insert(data_path="location", frame=i)

if color == red:
    color = blue
else:
    color = red

location += [1,0,0]

change this path to an absolute path on your computer

bpy.ops.wm.save_as_mainfile(filepath='C:/Users/m/Desktop/test_render.blend')

This does not produce the desired behavior. I can see the the material's base color property has the diamond symbol to the right, indicating it is keyframed. But the cube does not change to blue at any frame. What am I missing? Do I have to change the current value rather than the default value? I tried this, but there is no "value" data path.

Thanks!

  • 1
    You forgot to set the color value before inserting the keyframe in the forloop. Set the current frame to i, set the color and insert the keyframe. – X Y Jul 18 '23 at 00:23
  • yeah you forgot to call base_color.default_value = color before the keyframe_insert line. and your line blue = [1,0,1,1] is not blue. that is pink. set it to blue = [0,0,1,1] instead. optionally if you prefer, you can have a one liner for the if/else part like color = blue if color == red else red – Harry McKenzie Jul 18 '23 at 00:56
  • 1
    Ahh I see, thank you both! – 343GuiltySpark Jul 18 '23 at 15:16

1 Answers1

0

As with most issues it turned out to be a silly problem. I forgot to set base_color.default_value = color as mentioned in the comments.