How to get material with Python API in Blender

GOAL

To get material and its properties with Python API in Blender

Environment

Blender 2.83
Windows 10

Methods

How to get material

Method1. Get active material

Active material is the material currently selected in the material slot. If you select a face, the active material changes to the material assigned the selected face.

The following is the script to get active material of an object named “Cube”.

import bpy
obj = bpy.data.objects["Cube"]
material = obj.active_material
print(material)
# output => <bpy_struct, Material("Material3")>

Method2. Get material slots and select one of them

import bpy
obj = bpy.data.objects["Cube"]
material_slots = obj.material_slots
for m in material_slots:
    material = m.material
    print("slot", m, "material", material)

# output is material slot and material
# slot <bpy_struct, MaterialSlot("Material")> material <bpy_struct, Material("Material")>
# slot <bpy_struct, MaterialSlot("Material2")> material <bpy_struct, Material("Material2")>
# slot <bpy_struct, MaterialSlot("Material3")> material <bpy_struct, Material("Material3")>

You can get a slot with index or key (material name). The order of slots follows the order on material slot UI.

import bpy
obj = bpy.data.objects["Cube"]
material_slots = obj.material_slots

material1 = material_slots[0].material
print(material1)
# output => <bpy_struct, Material("Material")>
material2 = material_slots["Material2"].material
print(material2)
# output => <bpy_struct, Material("Materia2")>

Method3. Get from bpy.data.materials

You can get existing material by its key (Material name).

import bpy
material = bpy.data.materials["Material2"]

How to get material properties

You can see the material properties in the material properties tab. The way to get the value of properties is different according to the renderer.

Renderer: workbench

You can get the value of properties by using attributes of Material class as below.

import bpy
material = bpy.data.materials["Material.001"]

color = material.diffuse_color
print(color[0], color[1], color[2], color[3])
# output => 0.20000000298023224 0.800000011920929 0.5 1.0

metallic = material.metallic
print(metallic)
# output => 0.30000001192092896

Other renderers

For example, Principled BSDF is one of the node based materials in Eevee.

Access the node_tree of the Material object. And get the node “Principled BSDF” and get inputs of the node.

You can see the list of inputs by material.node_tree.nodes[“Principled BSDF”].inputs

import bpy
#obj = bpy.data.objects["Cube"]
#material = obj.active_material
material = bpy.data.materials["Material3"]

inputs = material.node_tree.nodes["Principled BSDF"].inputs
for i in inputs:
    print(i)
# output
# <bpy_struct, NodeSocketColor("Base Color")>
# <bpy_struct, NodeSocketFloatFactor("Subsurface")>
# <bpy_struct, NodeSocketVector("Subsurface Radius")>
# <bpy_struct, NodeSocketColor("Subsurface Color")>
# <bpy_struct, NodeSocketFloatFactor("Metallic")>

You can get node sockets with index or key(input name). And the value of unconnected input can be get with attribute “default_value

import bpy
material = bpy.data.materials["Material3"]

inputs = material.node_tree.nodes["Principled BSDF"].inputs
color = inputs["Base Color"].default_value
print(color[0], color[1], color[2], color[3])
# output => 0.15000000596046448 0.800000011920929 0.10000000149011612 1.0

subsurface = inputs["Subsurface"].default_value
print(subsurface)
# output => 0.0

How to change material properties

Substitute value for the attribute.

import bpy
material = bpy.data.materials["Material3"]

inputs = material.node_tree.nodes["Principled BSDF"].inputs
color = inputs["Base Color"].default_value
color[0] = 1.0

The color will change.

You can use the python array as the value of color.

import bpy
material = bpy.data.materials["Material.001"]
material.diffuse_color = [1.0, 0.2, 0.2 ,1.0]