I am familiar with scripting, a fair bit, but I dont know how to tackle this challenge...

I have a big amount of Materials with a principle BSDF and I need to disconnect the ImageTexture
from the Roughness-Channel insert a invert node and reconnect everything.

Maybe I can check the nodeTree which Map is connected to Roughness, save that - disconnect, insert and
reconnect, and go to the next tree...

but I dont have any clue how that could happen....


2 Answers 2


I propose the following script for this.

Basically, you access each material in the file, then get a reference to the image texture and bsdf nodes, then create a new invert node and connect everything. You don't care about unlinking first because it will be overwritten by your new link.

import bpy

for mat in bpy.data.materials:
    node_tree = mat.node_tree
    if not node_tree:

    # Get a reference to the image and bsdf nodes
    tex_image = bsdf = None
    for node in node_tree.nodes:
        if node.type == 'TEX_IMAGE':
            tex_image = node
        elif node.type == 'BSDF_PRINCIPLED':
            bsdf = node
    # If you have several Image Texture nodes, you can access a specific one by its name
    # tex_image = node_tree.nodes.get("Image Texture") # (Or whatever the name of the image texture node connected to the roughness channel usually is)

    if not (tex_image and bsdf):

    invert_node = node_tree.nodes.new(type='ShaderNodeInvert')
    invert_node.location = (-200, 50) 
    tex_image.location = (-600, 50)
    # Update the links. We don't care about unlinking because the current links will get overwritten
    links = node_tree.links
    links.new(tex_image.outputs[0], invert_node.inputs[1])
    links.new(invert_node.outputs[0], bsdf.inputs["Roughness"])

enter image description here

  • $\begingroup$ Ok, great, that works... but how do I check if bsdf.inputs["Roughness"] is unconnected before.... so that only already connected nodes get the Invert -- can I check if input[""] == none? $\endgroup$ Jun 19, 2020 at 11:50
  • 1
    $\begingroup$ I cant edit my comment, so here we go... I put "if bsdf.inputs["Roughness"].links:" in front of your invert node, where you make the links and now it works only for allready connected nodes. thx $\endgroup$ Jun 19, 2020 at 12:01
  • $\begingroup$ Oh, I didn't know you needed that but I am glad you solved it yourself :) $\endgroup$
    – Gorgious
    Jun 19, 2020 at 12:06
  • $\begingroup$ Yes, some failsafe is everytimes good, - if nothing is connected then dont do nothing... if you think that will improve your answer, maybe you would like to integrated in your answer so people facing the same problem can have a proper helpful answer.thx $\endgroup$ Jun 19, 2020 at 12:16

Look for the links

Similarly as in Blender scripting connect nodes look for the links.

In this case a link from an image texture node to the roughness socket of the bsdf node.

Test script, looks for that link(s) in all materials and if found inserts an invert node between.

import bpy

for m in bpy.data.materials:
    if not m.use_nodes:
    nodes = m.node_tree.nodes
    links = m.node_tree.links
    image_ps_links = [
        l for l in links 
        if l.from_node.type == "TEX_IMAGE" 
        and l.to_node.type == 'BSDF_PRINCIPLED'
        and l.to_socket.name == "Roughness"]
    for l in image_ps_links:
        invert_node = nodes.new(type='ShaderNodeInvert')
        links.new(l.from_socket, invert_node.inputs[1])
        links.new(invert_node.outputs[0], l.to_socket)

Note: Using the socket name "Roughness" may not work if you are using a language other than english. If this is the case would need to translate or use a method that takes into account the socket index.


You must log in to answer this question.

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