I saw in this youtube demonstration, that this is possible. I just can't imagine where I can change the default shader. I want the diffuse white shader to be a diffuse white Principled BSDF when I click the "+" in the material slots. Any ideas?

As Duarte Farrajota Ramos pointed out, the video was captured from the EEVEE branch (2.8). The Principled BSDF shader is the default shader there, so there wasn't any customization done to achive this behavior.

How would someone write a script or add-on to do this in pre 2.79 series?

  • 1
    $\begingroup$ That video is from experimental Blender 2.8 test builds and it is using EEVEE as default render engine, as far as I know this is not easy to achieve in 2.7# series, at least not without some scripting $\endgroup$ Commented Jan 4, 2018 at 13:01
  • $\begingroup$ @DuarteFarrajotaRamos you are right, I tried the same in 2.8 and the principled shader gets created by default. Unfortunately I am really bad at scripting, so this will have to wait. $\endgroup$
    – yann
    Commented Jan 4, 2018 at 13:05
  • 1
    $\begingroup$ The pieces are all here: App_handler to watch when a new material is added (watching the size of bpy.data.materials list): blender.stackexchange.com/a/19669/7777 and changing this material nodes: blender.stackexchange.com/a/23446/7777 $\endgroup$ Commented Jan 4, 2018 at 13:16

2 Answers 2


This script adds an app handler triggered on scene update. That runs my watch_materials function. First the watch_materials function checks to be sure you are using cycles. Then if there is another material it goes to the active object's active material and changes the node.

import bpy
from bpy.app.handlers import persistent

mat_count = len(bpy.data.materials)

def watch_materials(something):
    global mat_count
    if bpy.context.scene.render.engine == 'CYCLES':
        if len(bpy.data.materials) > mat_count:
            mat_count = len(bpy.data.materials)

            #get active object's active material
            node_tree = bpy.context.active_object.active_material.node_tree
            #save the location of the diffuse node
            location = node_tree.nodes['Diffuse BSDF'].location.copy()
            #delete that node
            node_tree.nodes.remove(node_tree.nodes['Diffuse BSDF'])
            #add new Principled node
            principled = node_tree.nodes.new('ShaderNodeBsdfPrincipled')
            # move it to where the diffuse node used to be
            principled.location = location
            #make the connection
            node_tree.links.new(principled.outputs['BSDF'], node_tree.nodes['Material Output'].inputs['Surface'])


Just copy that script into blender's text editor and press the "Run Script" button. After that any new materials you add will look like this.
Principled BSDF node in default material

Granted, there are still things that could be done to this script. For example if you added a new material without the default nodes (can only be done through python) my script will break.

I have to mention Jerryno, his comment pointed me towards the app handler. I had made a version of this using a timer driven modal, it was nice, but far more complex (it works too).


Its not exactly what you want but a very quick work around.

You could always just create the shader you want click the "F" so it doesn't disappear when you close blender and then CTRL+U to save as your start up file.

These are the shaders that always start up with my blend file.

enter image description here

enter image description here

  • $\begingroup$ sorry, but this is not what I'm looking for $\endgroup$
    – yann
    Commented Jan 28, 2018 at 15:12

You must log in to answer this question.

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