Node Scripting#

You have already seen the power of the node trees in Blender, and now you can make them with Python script.

Shader Nodes#

Continuing from the last section, after creating a new material with use_nodes turned on

mat = bpy.data.materials.new("new_mat")
mat.use_nodes = True

You will need the Material Output but not necessarily the Principled BSDF node. To delete a node, use

mat.node_tree.nodes.remove(mat.node_tree.nodes['Principled BSDF'])

To add nodes to the node tree, specify their type and assign them to a variable for later use

Tip

Check shader node type(subclasses) here.

fresnel_0 = mat.node_tree.nodes.new("ShaderNodeFresnel")
math_node_0 = mat.node_tree.nodes.new("ShaderNodeMath")
#move the nodes bit for demostration
fresnel_0.location = (-200, 300)
math_node_0.location = (0, 300)

You can tweak the nodes and change the inputs for unconnected sockets

Tip

  • Check math operation types here.

  • You may think it is much easier to do math in Python compared to using Math nodes, but Blender will not be able to compile the shader without them.

  • You can specify the socket by its name or index, but using index will be easier if a node have multiple sockets with the same name.

math_node_0.operation = "MULTIPLY"
math_node_0.inputs[1].default_value = 0.7

then connect the nodes

mat.node_tree.links.new(fresnel_0.outputs[0], math_node_0.inputs[0])
mat.node_tree.links.new(math_node_0.outputs[0], mat.node_tree.nodes['Material Output'].inputs[0])
../../_images/s_node_demo.gif

Note

The nodes will stack on each other in the shader editor if you don not specify their location. An easy solution is to use the Node Arrange add-on, enable it and select a node in the editor, then Left Mouse Click Arrange > Node Arrange > Arrange All Nodes.

Geometry Nodes#

You can create a new geometry node group in the data by

new_geom_group = bpy.data.node_groups.new("GROUP_NAME", "GeometryNodeTree")

Unlike a new geometry node group created in the GUI, this new group is empty, with no Group Input or Group Output nodes. You can add them back

geom_input = new_geom_group.nodes.new("NodeGroupInput")
geom_output = new_geom_group.nodes.new("NodeGroupOutput")

Tip

  • Check socket type(subclasses) here.

  • Check geometry node type(subclasses) here. Some nodes, like Value and Math, are the same as shader nodes you can find them there.

but these nodes will have no input/output sockets. To create new sockets, you need to add them directly to the node group

new_geom_group.inputs.new("NodeSocketGeometry", "Geometry")
new_geom_group.outputs.new("NodeSocketGeometry", "Geometry")

and now you have the familiar starting node tree. Adding and connecting nodes are the same as in shader nodes.

As explained in the previous chapter, applying geometry nodes to an object requires adding a Geometry Nodes modifier.

obj.modifiers.new("MODIFIER_NAME", "NODES")
obj.modifiers["MODIFIER_NAME"].node_group = new_geom_group

Compositor Nodes#

Enabling compositor nodes for the current scene is simple

bpy.context.scene.use_nodes = True

and you may want to make a convenience variable for the node tree

compo_nodes = bpy.context..scene.node_tree

Tip

Check compositor node type(subclasses) here.

Adding and connecting nodes are the same as above.