5
$\begingroup$

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 brdf, when I click the "+" in the material slots. Any ideas?

Edit

As Duarte Farrajota Ramos pointed out, the video was captured from the Evee branch (2.8). The principled brdf shader is the default shader there, so there wasn't any customization done to archive this behavior. Is someone interested in writing a small script or add-on for this? I will place a bounty as a small reward for your efforts.

$\endgroup$
  • 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$ – Duarte Farrajota Ramos Jan 4 '18 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 Jan 4 '18 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$ – Jaroslav Jerryno Novotny Jan 4 '18 at 13:16
7
+200
$\begingroup$

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)

@persistent
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'])

bpy.app.handlers.scene_update_post.append(watch_materials)

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).

$\endgroup$
3
$\begingroup$

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.