Defining Material with Python

Dear Blender users,
I am currently developing a script to load molecular structures into Blender.
It is based on the following code, but supports some different file formats:
blmol source

Anyway, everything is working nicely and I can plot not only simple structures but also isosurfaces (molecular orbitals, electron densities, …).
Here are some images:
This is with the current default materials.
blender_tutorial_wf
After tweaking by hand things can look quite fancy.

I am now looking for a way to implement nice default materials using python.

Currently my materials only use a BsdfPrincipled node with color and alpha taken from some dictionary that contains colors for every chemical element.


This node setup is created with the following script:

    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type="ShaderNodeBsdfPrincipled")
    bsdf.inputs[0].default_value = color
    bsdf.inputs[18].default_value = alpha

    node_output = nodes.new(type="ShaderNodeOutputMaterial")
    node_output.location = 400, 0

    links = mat.node_tree.links
    link = links.new(bsdf.outputs[0], node_output.inputs[0])

I am struggling to connect more nodes. Especially, I want to add an AmbientOcclusion node with a color ramp, as shown in the node setup below.

But I did not find a good tutorial that explains how to create ColorRamps in Blender (2.81).
Any suggestions on the coding part?
Also, if you have suggestions for nice material settings, do not hesitate to tell me. :slight_smile:

Best regards
Trichter

I had some trouble figuring out ColorRamps as well, I hope this helps! :slight_smile:

val_to_rgb = nodes.new('ShaderNodeValToRGB')
elements = val_to_rgb.color_ramp.elements
# accessing/assigning color
# first color
elements[0].color = (1,1,1,1)
# add new color and set its position
# position (float in [0, 1]) 
elements.new(0.5)

Thank you very much. It works nicely. I can now easily tune the amount of AO on my objects. :smiley:

molecule_ao

This is the code I am using (maybe it helps someone else):

    nodescale = 300

    mat = bpy.data.materials.new(name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type="ShaderNodeBsdfPrincipled")
    bsdf.location = 2*nodescale, 0
    bsdf.inputs[0].default_value = color
    bsdf.inputs[18].default_value = alpha

    ao = nodes.new(type="ShaderNodeAmbientOcclusion")
    ao.location = 0*nodescale, 0

    val_to_rgb = nodes.new(type="ShaderNodeValToRGB")
    val_to_rgb.location = 1*nodescale, 0
    elements = val_to_rgb.color_ramp.elements
    elements[0].color = COLORS['black']
    elements[0].position = 0.5
    #elements.new(1.)
    elements[1].color = color
    elements[1].position = 1.



    node_output = nodes.new(type="ShaderNodeOutputMaterial")
    node_output.location = 3*nodescale, 0

    links = mat.node_tree.links
    link = links.new(ao.outputs[0], val_to_rgb.inputs[0])
    link = links.new(val_to_rgb.outputs[0], bsdf.inputs[0])
    link = links.new(bsdf.outputs[0], node_output.inputs[0])