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
        color = red

    location += [1,0,0]

# change this path to an absolute path on your computer

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.


  • 1
    $\begingroup$ 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. $\endgroup$
    – X Y
    Jul 18, 2023 at 0:23
  • $\begingroup$ 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 $\endgroup$ Jul 18, 2023 at 0:56
  • 1
    $\begingroup$ Ahh I see, thank you both! $\endgroup$ Jul 18, 2023 at 15:16

1 Answer 1


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.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .