1
$\begingroup$

I'm making a motion graphics. All elements (in hundreds) are modeled in diffuse and have different colours. How do I select them all and change to emission shader without affecting the colors?

$\endgroup$
  • $\begingroup$ You can change node type with Node Wrangler addon, if it's enabled press Shift+S with node selected and choose node to change to. But that will change for one material. Maybe scripting is the best way for multiple. $\endgroup$ – Mr Zak May 14 '17 at 11:52
3
$\begingroup$

This script from http://web.purplefrog.com/~thoth/blender/python-cookbook/change-diffuse-to-emission-node.html should work

import bpy

def replace_with_emission(node, node_tree):
    new_node = node_tree.nodes.new('ShaderNodeEmission')
    connected_sockets_out = []
    sock = node.inputs[0]
    if len(sock.links)>0:
        color_link = sock.links[0].from_socket
    else:
        color_link=None
    defaults_in = sock.default_value[:]

    for sock in node.outputs:
        if len(sock.links)>0:
            connected_sockets_out.append( sock.links[0].to_socket)
        else:
            connected_sockets_out.append(None)

    #print( defaults_in )

    new_node.location = (node.location.x, node.location.y)

    if color_link is not None:
        node_tree.links.new(new_node.inputs[0], color_link)
    new_node.inputs[0].default_value = defaults_in

    if connected_sockets_out[0] is not None:
        node_tree.links.new(connected_sockets_out[0], new_node.outputs[0])


def material_diffuse_to_emission(mat):

    doomed=[]
    for node in mat.node_tree.nodes:
        if node.type=='BSDF_DIFFUSE':
            replace_with_emission(node, mat.node_tree)
            doomed.append(node)

    # wait until we are done iterating and adding before we start wrecking things
    for node in doomed:
        mat.node_tree.nodes.remove(node)


def replace_on_selected_objects():
    mats = set()
    for obj in bpy.context.scene.objects:
        if obj.select:
            for slot in obj.material_slots:
                mats.add(slot.material)

    for mat in mats:
        material_diffuse_to_emission(mat)

def replace_in_all_materials():
    for mat in bpy.data.materials:
        material_diffuse_to_emission(mat)


if True:
    replace_on_selected_objects()
else:
    replace_in_all_materials()

Just paste a copy into a blender Text Editor, select the objects you want adjusted, and click the Run Script button. If you want to rework all the materials, just change the tail end of the script to run the replace_in_all_materials() function.

$\endgroup$

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.