# coding: utf-8 # Copyright (C) 2023 Ilia Kurochkin # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. ''' DESCRIPTION. Set up materials. ''' __version__ = '0.1' import logging import os import bpy logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def assign_pbr_material(obj_names, textures_path): ''' Assign material with PBR textures pack. ''' textures = sorted(os.listdir(textures_path)) for obj_name in obj_names: part_name = obj_name.rpartition('_')[0] obj = bpy.data.objects[obj_name] if len(obj.material_slots) > 0: # should be only one material so clear all exist slots obj.data.materials.clear() if part_name in bpy.data.materials: # if material is already in scene obj.data.materials.append(bpy.data.materials[part_name]) continue # create Principled BSDF based material bmat = bpy.data.materials.new(name=part_name) bmat.use_nodes = True principled_node = bmat.node_tree.nodes["Principled BSDF"] for texture in textures: print(1, 'texture', texture) if not texture.startswith('T_' + part_name): continue print(2, 'texture', texture) if '_ao.' in texture: image_obj = bpy.data.images.load(os.path.join(textures_path, texture)) image_obj.colorspace_settings.name = 'Linear' texture_ao = bmat.node_tree.nodes.new(type="ShaderNodeTexImage") texture_ao.location = -1000, 500 texture_ao.image = bpy.data.images[image_obj.name] mix_node = bmat.node_tree.nodes.new(type="ShaderNodeMix") mix_node.location = -500, 500 #mix_node.data_type = 'RGBA' mix_node.blend_type = 'MULTIPLY' mix_node.inputs['Factor'].default_value = 0.5 bmat.node_tree.links.new(texture_ao.outputs['Color'], mix_node.inputs['B']) bmat.node_tree.links.new(mix_node.outputs[0], principled_node.inputs['Base Color']) if '_d.' in texture: image_obj = bpy.data.images.load(os.path.join(textures_path, texture)) image_obj.colorspace_settings.name = 'sRGB' texture_d = bmat.node_tree.nodes.new(type="ShaderNodeTexImage") texture_d.location = -1000, 0 texture_d.image = bpy.data.images[image_obj.name] if texture_ao: bmat.node_tree.links.new(texture_d.outputs['Color'], mix_node.inputs['A']) else: bmat.node_tree.links.new(texture_d.outputs['Color'], principled_node.inputs['Base Color']) if '_m.' in texture: image_obj = bpy.data.images.load(os.path.join(textures_path, texture)) image_obj.colorspace_settings.name = 'Linear' texture_m = bmat.node_tree.nodes.new(type="ShaderNodeTexImage") texture_m.location = -1000, -500 texture_m.image = bpy.data.images[image_obj.name] bmat.node_tree.links.new(texture_m.outputs['Color'], principled_node.inputs['Metallic']) if '_r.' in texture: image_obj = bpy.data.images.load(os.path.join(textures_path, texture)) image_obj.colorspace_settings.name = 'Linear' texture_r = bmat.node_tree.nodes.new(type="ShaderNodeTexImage") texture_r.location = -1000, -1000 texture_r.image = bpy.data.images[image_obj.name] bmat.node_tree.links.new(texture_r.outputs['Color'], principled_node.inputs['Roughness']) if '_n.' in texture: image_obj = bpy.data.images.load(os.path.join(textures_path, texture)) image_obj.colorspace_settings.name = 'Non-Color' texture_n = bmat.node_tree.nodes.new(type="ShaderNodeTexImage") texture_n.location = -1000, -1500 texture_n.image = bpy.data.images[image_obj.name] normal_node = bmat.node_tree.nodes.new(type="ShaderNodeNormalMap") normal_node.location = -500, -1500 bmat.node_tree.links.new(texture_n.outputs['Color'], normal_node.inputs['Color']) bmat.node_tree.links.new(normal_node.outputs['Normal'], principled_node.inputs['Normal']) obj.data.materials.append(bmat) logger.info('Shading of %s objects is finished!', len(obj_names)) return True