The Original Problem (SOLVED, thank you Gorgious) :
- When I import models, they have materials with "Specular BSDF".
- I'm looking to change all surfaces to "Principled BSDF".
- If I did this manually, it would look like this: https://i.sstatic.net/NjqNS.png
- This is what my shading tab looked like originally: https://i.sstatic.net/w4H5h.png
The script below is what I'm using, now. It converts the materials to Principle BSDF, then sets some properties, then flips the normals. This prepares me to take imported .mqo models and export them to .glb for 3D modeling purposes.
import bpy
# Convert Materials to Principled BSDF
for mat in bpy.data.materials:
if not mat.use_nodes:
continue
nodes = mat.node_tree.nodes
specular = next((n for n in nodes if isinstance(n, bpy.types.ShaderNodeEeveeSpecular)), None)
output = next((n for n in nodes if isinstance(n, bpy.types.ShaderNodeOutputMaterial)), None)
if specular is None or output is None:
continue
principled = nodes.new("ShaderNodeBsdfPrincipled")
principled.inputs[0].default_value = specular.inputs[0].default_value
principled.inputs[9].default_value = specular.inputs[2].default_value
principled.inputs[19].default_value = (0, 0, 0, 0)
principled.inputs[21].default_value = 1 - specular.inputs[4].default_value
principled.inputs[14].default_value = specular.inputs[6].default_value
principled.inputs[15].default_value = specular.inputs[7].default_value
principled.location = (specular.location[0] - 100, specular.location[1])
mat.node_tree.links.new(principled.outputs[0], output.inputs[0])
nodes.remove(specular)
# Set Material Properties
def remove_links(socket: bpy.types.NodeSocket, node_tree: bpy.types.NodeTree):
for link in socket.links:
node_tree.links.remove(link)
def fix_node(node: bpy.types.Node, node_tree: bpy.types.NodeTree):
if node.type == 'BSDF_PRINCIPLED':
node.inputs['Specular'].default_value = 0.5
node.inputs['Metallic'].default_value = 0.0
remove_links(node.inputs['Alpha'], node_tree)
remove_links(node.inputs['Normal'], node_tree)
def fix_material(material: bpy.types.Material):
for node in material.node_tree.nodes:
fix_node(node, material.node_tree)
def fix_selected():
for object in bpy.context.selected_objects:
for material_slot in object.material_slots:
fix_material(material_slot.material)
# Flip Normals
scn = bpy.context.scene
sel = bpy.context.selected_objects
meshes = [o for o in sel if o.type == 'MESH']
for obj in meshes:
bpy.context.view_layer.objects.active = obj
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.flip_normals()
bpy.ops.object.mode_set()
if __name__ == "__main__":
fix_selected()