0
$\begingroup$

I kindly ask for your help on the following:

  • I have created a custom node group that has 1 single image as an input enter image description here
  • I have a very large directory of textures to be used as input for this custom node group

as I'm not a programmer, I would like to know if there is a simple script that can create, in bulk, inside the Blend file, a series of materials that

  • look like the one in the screenshot
  • each one has a different image from the directory as an input
  • each one takes the name from the image

thank you in advance for any help you can give me

$\endgroup$

1 Answer 1

1
$\begingroup$

That can be this kind of script. Details are in comments in the code.

Note: material output in not in the image in the question, but I've added it in the script.

import bpy
import os

def get_images(directory):
    return os.listdir(directory)

def image_to_material(directory, image_name, pbr_group, replace = True):

    # if image and material are to be replaced    
    if replace:
        image = bpy.data.images.get(image_name)
        if image:
            bpy.data.images.remove(image)
        material = bpy.data.materials.get(image_name)
        if material:
            bpy.data.materials.remove(material)        
    
    # get the image
    image = bpy.data.images.load(os.path.join(directory, image_name))

    # create the material
    material = bpy.data.materials.new(image_name)
    material.use_nodes = True
    node_tree = material.node_tree
    principled = node_tree.nodes['Principled BSDF']
    node_tree.nodes.remove(principled) # default principled is removed in this case

    # insert the pbr group in the material tree
    group_node = node_tree.nodes.new(type='ShaderNodeGroup')
    group_node.node_tree = pbr_group

    # insert the image texture node
    image_node = node_tree.nodes.new(type="ShaderNodeTexImage")
    image_node.image = image

    # get the material output
    output_node = node_tree.nodes['Material Output']

    # link the image texture to the group and the group to material output
    node_tree.links.new(image_node.outputs[0], group_node.inputs[0])
    node_tree.links.new(group_node.outputs[0], output_node.inputs[0])

    # place them 
    group_node.location = (output_node.location.x - group_node.width - 100, output_node.location.y)
    image_node.location = (group_node.location.x - image_node.width - 100, group_node.location.y)


directory = "d:/temp/images" # your directory here

pbr_group_name = "test" # your node group name here
pbr_group = bpy.data.node_groups.get(pbr_group_name)

if pbr_group:
    # loop over image file names
    for image_name in get_images(directory):
        try:
            # create the material
            image_to_material(directory, image_name, pbr_group)
        except Exception as e:
            # in case, for instance, one of the files is not loadable
            print( f"An error occured for {image_name}", e)
else:
    print("Group not found")
$\endgroup$

You must log in to answer this question.

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