1
$\begingroup$

I have seen that a Python script can update several materials, that contain basically the same nodes, with simple value changes (Change multiple specific nodes in multiple materials (with python?))

I need to do something like this to affect over 2400 almost identical materials.

I have used a map globe downloaded from 3d Warehouse. This globe is black and white, and has been created by the designer using over 2400 jpegs of map squares and identical materials with unique jpeg names in the initial Base Colour node (see picture below).

The Material names are GLOBE_0 through to GLOBE_2448. If a node group had been used with the unique jpeg as input, I could change the node group to affect all. However, that was not the case.

I want to change the colour from black and white to gold and cream. I believe this update of the image could be created as a node group, with an input/output of Color, and slotted in between the Base Colour and Principled BSDF nodes. Although I am still a Blender novice, I will work out what this node group should contain (probably nick similar transformations in Blender STackExchange if I'm honest!). However, I don't know how the slotting in of a new node group would be scripted in Python.

The commonalities in all these materials are:

  1. Material names - GLOBE_0 through to GLOBE_2448
  2. A new node group - call it ColorGold
  3. Link between Base Colour and Principled BSDF nodes

Thanks in advance. Globe_0 material

$\endgroup$
1
$\begingroup$

Try this

import bpy

group_name = "ColorGold"

for mat in bpy.data.materials:
    if not mat.name.startswith("GLOBE_"): continue

    # Find Principled node
    for n in mat.node_tree.nodes:
        if n.type == 'BSDF_PRINCIPLED': break
    else: continue

    # Find Base Color texture node
    soc = n.inputs["Base Color"]
    if not soc.links: continue
    if soc.links[0].from_socket.name != "Color": continue
    tex = soc.links[0].from_node
    if tex.type != 'TEX_IMAGE': continue

    # Insert group node
    g = mat.node_tree.nodes.new("ShaderNodeGroup")
    g.node_tree = bpy.data.node_groups[group_name]
    g.location = tex.location[0] + 100, tex.location[1]
    tex.location = tex.location[0] - 250, tex.location[1]
    mat.node_tree.links.new(g.outputs[0], n.inputs["Base Color"])
    mat.node_tree.links.new(tex.outputs["Color"], g.inputs[0])
| improve this answer | |
$\endgroup$
  • $\begingroup$ That is perfect. Thank you so much. $\endgroup$ – stain Sep 7 at 18:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.