0
$\begingroup$

I am trying to animate, in Python, the colour of a node material using the Colour Ramp node, and I want to know the data path to give in keyframe statements.

I have made a material using the Colour Ramp node driven by a Math node. The Math node is animated to give the required colour changes. This works if I set up the system manually as shown below.

enter image description here

However in Python, although I can set up the material, I cannot find how to make keyframes – apparently the data path is incorrect. I enclose my Python code to set up the node material and set the first keyframe.

    import bpy
    #                        green      red
    colors =  [(0,0,0,0), (0,1,0,1), (1,0,0,1)]

    #create single cube and colour it green
    obj = bpy.data.objects['Cube']

    mat1 = bpy.data.materials.new(name = 'Material1')
    mat1.use_nodes = True
    obj.active_material = mat1

    # Build shader nodes
    pNode = mat1.node_tree.nodes.get('Principled BSDF')
    pNode.inputs[0].default_value = (0,0,1,1)
    crNode  = mat1.node_tree.nodes.new('ShaderNodeValToRGB')
    crNode.location = (-300, 200)
    mNode = mat1.node_tree.nodes.new('ShaderNodeMath')
    mNode.location = (-600, 200)

     # Build shader links   
    link = mat1.node_tree.links.new
    link(mNode.outputs[0],crNode.inputs[0])
    link(crNode.outputs[0],pNode.inputs[0])

    # set up color ramp points 0 and 1
    crNode.color_ramp.elements[0].color = (colors[1])
    crNode.color_ramp.elements[1].color = (colors[2])

    #Variable which sets the colour within the specified colour range (0 to 1)
    mNode.inputs[0].default_value = 0
    mNode.inputs[1].default_value = 0

    colNode = mat1.node_tree.nodes['Math']

    colNode.inputs[0].default_value = 1
    mat1.keyframe_insert(data_path = "colNode.inputs[0]", frame = 20)

It gives an error on the last line, with error message: File "C:\Users\Jim\aSk\GExercises\Test5a.blend\Test7CreateCubes.py", line 36, in TypeError: bpy_struct.keyframe_insert() property "colNode.inputs[0]" not found

I have tried different content for the data path, but all references I have looked at seem to suggest using the “node_tree.nodes” property which I am trying to do in the above code. So is there a simple solution, or is there something wrong in my fundamental thinking? What is the correct data path in the keyframe statement:

    mat1.keyframe_insert(data_path = "…..............", frame = 20) 

and how it is derived? I would be most thankful for any help.

$\endgroup$
1
  • $\begingroup$ colNode.inputs[0].keyframe_insert(data_path = "default_value", frame = 20) $\endgroup$
    – X Y
    Commented May 22, 2022 at 13:35

1 Answer 1

0
$\begingroup$

There are possibly two problems in your code: You're trying to use a Math node you don't need and you're not referencing the color node correctly when you call keyframe_insert.

  1. The math node, unless you need it for some other purpose:

Remove all of the references to mnode; fix the linking and change

    colNode.inputs[0].default_value = 1

to

    crNode.inputs[0].default_value = 1
  1. The call to keyframe_insert:

When you want to insert a keyframe on a property, you have to insert it on the thing that contains that property, in this case the actual node input, which contains the default_value field.

You can discover what that is by hovering over the field that you would use to insert a keyframe, right clicking, and selecting "Copy Data Path". If you do this with the Fac field of a color ramp you'll get something like node_tree.nodes["ColorRamp"].inputs[0].default_value Everything but the last field goes to the left of the keyframe_insert and the last field is the name to give to the data_path= argument of the function. So in this case,

node_tree.nodes["ColorRamp"].inputs[0].keyframe_insert(data_path="default_value", frame = FRAMENO)

is the generic form for inserting a keyframe into a Color Ramp's Fac setting; but one more step is necessary. You need to replace the generic node_tree.nodes["ColorRamp"] with the correct value from your code. Since you have the color node as crNode in your code, what you want is

crNode.inputs[0].keyframe_insert(data_path="default_value", frame=20)
  1. The resulting code
import bpy
#                        green      red
colors =  [(0,0,0,0), (0,1,0,1), (1,0,0,1)]

#create single cube and colour it green
obj = bpy.data.objects['Cube']

mat1 = bpy.data.materials.new(name = 'Material1')
mat1.use_nodes = True
obj.active_material = mat1

# Build shader nodes
pNode = mat1.node_tree.nodes.get('Principled BSDF')
pNode.inputs[0].default_value = (0,0,1,1)
crNode  = mat1.node_tree.nodes.new('ShaderNodeValToRGB')
crNode.location = (-300, 200)

# Build shader links   
link = mat1.node_tree.links.new
link(crNode.outputs[0],pNode.inputs[0])

# set up color ramp points 0 and 1
crNode.color_ramp.elements[0].color = (colors[1])
crNode.color_ramp.elements[1].color = (colors[2])

crNode.inputs[0].default_value = 1
crNode.inputs[0].keyframe_insert(data_path="default_value", frame=20)

You can, of course, keep the math nodes, in which case, since you already had mNode pointing at the math node, simply change the last two lines to use mNode rather than crNode.

$\endgroup$
2
  • $\begingroup$ To Marty Fouts: Thanks hugely for your clear and succinct explanation, and for correcting my code. To me, the key in your explanation is in the fact that the data path can be derived from the dev-tip on the "insert key" for the appropriate value (in the case of crNode, the "Fac" value; I did not know this, and it is a very useful tip. $\endgroup$
    – Jim Tucker
    Commented May 22, 2022 at 16:45
  • $\begingroup$ @JimTucker you are very welcome. I am glad I could help. Since you're apparently a new user to Blender StackExchange, you might want to read What should I do when someone answers my question? and perhaps upvote or accept my answer $\endgroup$ Commented May 22, 2022 at 19:13

You must log in to answer this question.

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