3
$\begingroup$

I am a newbie in Blender Python scripting. I am trying to write a simple script to link a texture node to a material node in Blender 2.82. I tried something close to the procedure described in How can I connect a texture node to a material with Python?

import os, bpy

bpy.context.scene.render.engine = 'CYCLES'

# new material
mat = bpy.data.materials.new('mat')
mat.use_nodes = True
matnodes = mat.node_tree.nodes

#new texture
tex = matnodes.new('ShaderNodeTexImage')
img = bpy.data.images.load(<file-path-on-disk>)
tex.image = img

# assign texture to material's displacement
disp = matnodes['Material Output'].inputs[2]
mat.node_tree.links.new(disp, tex.outputs[0])

The script runs with no error reported on the console. Yet the texture node does not show on the 'Shading' panel. Can anybody give me a clue as to what may be the problem?

$\endgroup$

1 Answer 1

5
$\begingroup$

The script works, however you don't assign the newly created material to any object. Therefore you're seeing the old material, that was previously assigned to the active object, in the Material Properties or the Shader Editor.

If you want to assign the material to the currently active material slot of the active object, you can use

bpy.context.view_layer.objects.active.active_material = mat

where mat is the material you've created in your script. Alternatively you can also assign the material to a specific material slot, e.g. the first one in the following example:

bpy.context.view_layer.objects.active.material_slots[0].material = mat

When you're performing multiple operations with the active object, you can store it in a variable. It's not necessary to access it through bpy.context all the time.


One problem with your script is that it creates a node setup which doesn't properly use displacement. Usually you'd want to add a Displacement node and control the height through the texture. You may also want to add a Texture Coordinate node to use the active UV map for the displacement texture.

import bpy


# Create a material
material = bpy.data.materials.new(name="Example_Material")
material.use_nodes = True
nodes = material.node_tree.nodes
links = material.node_tree.links

# Reuse the material output node that is created by default
material_output = nodes.get("Material Output")

# Create Image Texture node and load the displacement texture.
# You need to add the actual path to the texture.
displacement_tex = nodes.new("ShaderNodeTexImage")
displacement_tex.image = bpy.data.images.load("/path/to/your/texture")
displacement_tex.image.colorspace_settings.name = "Non-Color"

# Create the Displacement node
displacement = nodes.new("ShaderNodeDisplacement")

# Create the Texture Coordinate node
tex_coordinate = nodes.new("ShaderNodeTexCoord")

# Connect the Texture Coordinate node to the displacement texture.
# This uses the active UV map of the object.
links.new(displacement_tex.inputs["Vector"], tex_coordinate.outputs["UV"])

# Connect the displacement texture to the Displacement node
links.new(displacement.inputs["Height"], displacement_tex.outputs["Color"])

# Connect the Displacement node to the Material Output node
links.new(material_output.inputs["Displacement"], displacement.outputs["Displacement"])

# Get the active object
active_obj = bpy.context.view_layer.objects.active

# Check if the active object has a material slot, create one if it doesn't. 
# Assign the material to the first slot for the active object.
if active_obj.material_slots:
    active_obj.material_slots[0].material = material
else:
    active_obj.material_slots.append(material)

For Adaptive Displacement you will also have to set the Feature Set to experimental

bpy.context.scene.cycles.feature_set = 'EXPERIMENTAL'

and enable the Adaptive option in the Subdivision Surface modifier. You may have to adjust the Subdivision options in the Render Properties as well, in order to get the desired amount detail for the displacement.

$\endgroup$
3
  • $\begingroup$ Thanks a million! $\endgroup$
    – user89301
    Feb 27, 2020 at 1:13
  • $\begingroup$ @user89301 If my answer solved your problem, please consider marking it as accepted by clicking on the checkmark next to it. $\endgroup$
    – Robert Gützkow
    Feb 27, 2020 at 8:33
  • $\begingroup$ Thanks a million! $\endgroup$
    – JavaRunner
    Dec 27, 2021 at 0:01

You must log in to answer this question.

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