588 lines
24 KiB
Python
588 lines
24 KiB
Python
import bpy
|
|
from bpy.types import ObjectShaderFx
|
|
import mathutils
|
|
from .. Functions import node_functions
|
|
from .. Functions import image_functions
|
|
from .. Functions import constants
|
|
from .. Functions import visibility_functions
|
|
from .. Functions import material_functions
|
|
|
|
blender_version = bpy.app.version
|
|
|
|
class BakeUtilities():
|
|
C = bpy.context
|
|
D = bpy.data
|
|
O = bpy.ops
|
|
|
|
all_materials = None
|
|
image_texture_nodes = None
|
|
bake_settings = None
|
|
bake_image = None
|
|
render_engine = None
|
|
selected_objects = None
|
|
image_size = None
|
|
parent_operator = None
|
|
tex_node_name = None
|
|
|
|
def __init__(self,parent_operator,selected_objects, bake_settings):
|
|
self.C = bpy.context
|
|
self.D = bpy.data
|
|
self.parent_operator = parent_operator
|
|
self.render_engine = self.C.scene.render.engine
|
|
self.selected_objects = selected_objects
|
|
self.all_materials = self.D.materials
|
|
self.selected_materials = material_functions.get_selected_materials(self.selected_objects)
|
|
self.bake_settings = bake_settings
|
|
self.baked_images = []
|
|
self.image_texture_nodes = set()
|
|
self.image_size = [int(self.C.scene.img_bake_size),
|
|
int(self.C.scene.img_bake_size)]
|
|
image_name = bake_settings.bake_image_name
|
|
|
|
self.bake_image = image_functions.create_image(image_name, self.image_size)
|
|
|
|
def setup_engine(self):
|
|
# setup engine
|
|
if self.render_engine == 'BLENDER_EEVEE':
|
|
self.C.scene.render.engine = 'CYCLES'
|
|
|
|
# setup device type
|
|
self.cycles_device_type = self.C.preferences.addons['cycles'].preferences.compute_device_type
|
|
if self.cycles_device_type == 'OPTIX':
|
|
self.C.preferences.addons['cycles'].preferences.compute_device_type = 'CUDA'
|
|
|
|
# setup samples
|
|
if self.bake_settings.pbr_bake:
|
|
self.C.scene.cycles.samples = self.bake_settings.pbr_samples
|
|
if self.bake_settings.lightmap_bake:
|
|
self.C.scene.cycles.samples = self.bake_settings.lightmap_samples
|
|
if self.bake_settings.ao_bake:
|
|
self.C.scene.cycles.samples = self.bake_settings.ao_samples
|
|
|
|
self.C.scene.render.resolution_percentage = 100
|
|
|
|
def set_active_uv_to_lightmap(self):
|
|
bpy.ops.object.set_active_uv(uv_slot=2)
|
|
|
|
def checkPBR(self):
|
|
for material in self.selected_materials:
|
|
self.active_material = material
|
|
# check if pbr node exists
|
|
check_ok = node_functions.check_pbr(self.parent_operator,material)
|
|
if not check_ok :
|
|
self.parent_operator.report({'INFO'}, "Material " + material.name + " has no PBR Node !")
|
|
return check_ok
|
|
|
|
def unwrap_selected(self):
|
|
if self.bake_settings.unwrap:
|
|
self.O.object.add_uv(uv_name=self.bake_settings.uv_name)
|
|
|
|
# apply scale on linked
|
|
sel_objects = self.C.selected_objects
|
|
scene_objects = self.D.objects
|
|
linked_objects = set()
|
|
|
|
for sel_obj in sel_objects:
|
|
for scene_obj in scene_objects:
|
|
if sel_obj.data.original is scene_obj.data and sel_obj is not scene_obj:
|
|
linked_objects.add(sel_obj)
|
|
|
|
# do not apply transform if linked objects in selection
|
|
if not len(linked_objects)>0:
|
|
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
|
|
|
|
|
|
self.O.object.mode_set(mode='EDIT')
|
|
self.O.mesh.reveal()
|
|
self.O.mesh.select_all(action='SELECT')
|
|
self.O.uv.smart_project(island_margin=self.bake_settings.unwrap_margin)
|
|
self.O.object.mode_set(mode='OBJECT')
|
|
|
|
def create_bake_material(self,material_name_suffix):
|
|
|
|
bake_materials = []
|
|
selected_materials = []
|
|
for obj in self.selected_objects:
|
|
for slot in obj.material_slots:
|
|
selected_materials.append(slot.material)
|
|
|
|
# switch to ao material if we are on org and ao was already baked
|
|
visibility_functions.switch_baked_material(True,"scene")
|
|
|
|
for obj in self.selected_objects:
|
|
for slot in obj.material_slots:
|
|
material = slot.material
|
|
bake_material_name = material.name + material_name_suffix
|
|
|
|
# check if material was already baked and continue
|
|
if material_name_suffix in material.name:
|
|
bake_materials.append(material)
|
|
continue
|
|
|
|
# if not, copy material or take one out of the previewsly filled bake list
|
|
else :
|
|
bake_material = list(filter(lambda material: material.name == bake_material_name, bake_materials))
|
|
|
|
if len(bake_material) == 0:
|
|
bake_material = material.copy()
|
|
bake_material.name = bake_material_name
|
|
bake_materials.append(bake_material)
|
|
slot.material = bake_material
|
|
|
|
else:
|
|
bake_material = bake_material[0]
|
|
slot.material = bake_material
|
|
|
|
index = bake_material.name.find(".")
|
|
if index == -1:
|
|
obj.bake_version = ""
|
|
else:
|
|
obj.bake_version = bake_material.name[index:]
|
|
|
|
material.use_fake_user = True
|
|
|
|
|
|
# remove duplicate entries
|
|
self.selected_materials = list(set(bake_materials))
|
|
|
|
def add_gltf_material_output_node(self, material):
|
|
nodes = material.node_tree.nodes
|
|
|
|
name = "glTF Material Output"
|
|
gltf_node_group = bpy.data.node_groups.new(name, 'ShaderNodeTree')
|
|
gltf_node_group.inputs.new("NodeSocketFloat", "Occlusion")
|
|
thicknessFactor = gltf_node_group.inputs.new("NodeSocketFloat", "Thickness")
|
|
thicknessFactor.default_value = 0.0
|
|
gltf_node_group.nodes.new('NodeGroupOutput')
|
|
gltf_node_group_input = gltf_node_group.nodes.new('NodeGroupInput')
|
|
specular = gltf_node_group.inputs.new("NodeSocketFloat", "Specular")
|
|
specular.default_value = 1.0
|
|
specularColor = gltf_node_group.inputs.new("NodeSocketColor", "Specular Color")
|
|
specularColor.default_value = [1.0,1.0,1.0,1.0]
|
|
gltf_node_group_input.location = -200, 0
|
|
|
|
|
|
gltf_settings_node = nodes.get(name)
|
|
if gltf_settings_node is None:
|
|
gltf_settings_node = nodes.new('ShaderNodeGroup')
|
|
gltf_settings_node.name = name
|
|
gltf_settings_node.node_tree = bpy.data.node_groups[name]
|
|
|
|
return gltf_settings_node
|
|
|
|
|
|
|
|
|
|
def add_gltf_settings_node(self, material):
|
|
nodes = material.node_tree.nodes
|
|
# create group data
|
|
gltf_settings = bpy.data.node_groups.get('glTF Settings')
|
|
if gltf_settings is None:
|
|
bpy.data.node_groups.new('glTF Settings', 'ShaderNodeTree')
|
|
|
|
# add group to node tree
|
|
gltf_settings_node = nodes.get('glTF Settings')
|
|
if gltf_settings_node is None:
|
|
gltf_settings_node = nodes.new('ShaderNodeGroup')
|
|
gltf_settings_node.name = 'glTF Settings'
|
|
gltf_settings_node.node_tree = bpy.data.node_groups['glTF Settings']
|
|
|
|
# create group inputs
|
|
if gltf_settings_node.inputs.get('Occlusion') is None:
|
|
gltf_settings_node.inputs.new('NodeSocketFloat','Occlusion')
|
|
|
|
return gltf_settings_node
|
|
|
|
def add_image_texture_node(self, material):
|
|
nodes = material.node_tree.nodes
|
|
|
|
# add image texture
|
|
if self.bake_settings.lightmap_bake:
|
|
self.tex_node_name = self.bake_settings.texture_node_lightmap
|
|
|
|
if self.bake_settings.ao_bake:
|
|
self.tex_node_name = self.bake_settings.texture_node_ao
|
|
|
|
image_texture_node = node_functions.add_node(material, constants.Shader_Node_Types.image_texture, self.tex_node_name)
|
|
image_texture_node.image = self.bake_image
|
|
self.bake_image.colorspace_settings.name = "Linear FilmLight E-Gamut"
|
|
nodes.active = image_texture_node
|
|
|
|
# save texture nodes and pbr nodes for later
|
|
self.image_texture_nodes.add(image_texture_node)
|
|
|
|
return image_texture_node
|
|
|
|
def save_metal_value(self):
|
|
for material in self.selected_materials:
|
|
pbr_node = node_functions.get_pbr_node(material)
|
|
|
|
# save metal value
|
|
metallic_value = pbr_node.inputs["Metallic"].default_value
|
|
pbr_node["original_metallic"] = metallic_value
|
|
pbr_node.inputs["Metallic"].default_value = 0
|
|
|
|
# save metal image
|
|
if pbr_node.inputs["Metallic"].is_linked:
|
|
|
|
# get metal image node, save it in pbr node and remove connection
|
|
metal_image_node_socket = pbr_node.inputs["Metallic"].links[0].from_socket
|
|
self.metal_image_node_output = metal_image_node_socket
|
|
node_functions.remove_link(material,metal_image_node_socket,pbr_node.inputs["Metallic"])
|
|
|
|
def load_metal_value(self):
|
|
for material in self.selected_materials:
|
|
pbr_node = node_functions.get_pbr_node(material)
|
|
pbr_node.inputs["Metallic"].default_value = pbr_node["original_metallic"]
|
|
|
|
# reconnect metal image
|
|
if hasattr(self,"metal_image_node_output"):
|
|
node_functions.make_link(material,self.metal_image_node_output,pbr_node.inputs["Metallic"])
|
|
|
|
def add_uv_node(self,material):
|
|
|
|
uv_node = node_functions.add_node(material, constants.Shader_Node_Types.uv, "Second_UV")
|
|
uv_node.uv_map = self.bake_settings.uv_name
|
|
return uv_node
|
|
|
|
def position_gltf_setup_nodes(self,material,uv_node,image_texture_node,gltf_settings_node):
|
|
nodes = material.node_tree.nodes
|
|
# uv node
|
|
pbr_node = node_functions.get_pbr_node(material)
|
|
pos_offset = mathutils.Vector((-900, 400))
|
|
loc = pbr_node.location + pos_offset
|
|
uv_node.location = loc
|
|
|
|
# image texture
|
|
loc = loc + mathutils.Vector((300, 0))
|
|
image_texture_node.location = loc
|
|
|
|
# ao node
|
|
loc = loc + mathutils.Vector((300, 0))
|
|
gltf_settings_node.location = loc
|
|
|
|
nodes.active = image_texture_node
|
|
|
|
def add_node_setup(self):
|
|
for material in self.selected_materials:
|
|
# AO
|
|
if self.bake_settings.ao_bake:
|
|
uv_node = self.add_uv_node(material)
|
|
image_texture_node = self.add_image_texture_node(material)
|
|
|
|
if blender_version <= (3, 3):
|
|
gltf_settings_node = self.add_gltf_settings_node(material)
|
|
else:
|
|
gltf_settings_node = self.add_gltf_material_output_node(material)
|
|
|
|
|
|
# position
|
|
self.position_gltf_setup_nodes(material,uv_node,image_texture_node,gltf_settings_node)
|
|
|
|
# linking
|
|
node_functions.make_link(material, uv_node.outputs["UV"],image_texture_node.inputs['Vector'])
|
|
node_functions.make_link(material, image_texture_node.outputs['Color'], gltf_settings_node.inputs['Occlusion'])
|
|
|
|
# LIGHTMAP
|
|
if self.bake_settings.lightmap_bake:
|
|
image_texture_node = self.add_image_texture_node(material)
|
|
uv_node = self.add_uv_node(material)
|
|
# position
|
|
image_texture_node.location = mathutils.Vector((-500, 200))
|
|
uv_node.location = mathutils.Vector((-700, 200))
|
|
|
|
# linking
|
|
node_functions.make_link(material, uv_node.outputs["UV"],image_texture_node.inputs['Vector'])
|
|
|
|
def bake(self,bake_type):
|
|
channels_to_bake = bake_type
|
|
self.baked_images = []
|
|
denoise = self.bake_settings.denoise
|
|
|
|
# no denoise
|
|
if not denoise:
|
|
channel = bake_type[0]
|
|
image = self.bake_images(self.bake_image,channel,denoise)
|
|
image_functions.save_image(image,False)
|
|
return
|
|
|
|
# bake channels for denoise
|
|
for channel in channels_to_bake:
|
|
image_name = self.bake_image.name + "_" + channel
|
|
image = image_functions.create_image(image_name,self.bake_image.size)
|
|
self.change_image_in_nodes(image)
|
|
baked_channel_image = self.bake_images(image,channel,denoise)
|
|
image_functions.save_image(image,True)
|
|
self.baked_images.append(baked_channel_image)
|
|
|
|
self.denoise()
|
|
|
|
def change_image_in_nodes(self,image):
|
|
for image_texture_node in self.image_texture_nodes:
|
|
if image_texture_node.name == self.tex_node_name:
|
|
image_texture_node.image = image
|
|
|
|
def bake_images(self, image, channel,denoise):
|
|
if channel == "NRM":
|
|
print("Baking Normal Pass")
|
|
self.C.scene.cycles.samples = 1
|
|
self.O.object.bake(type="NORMAL", use_clear=self.bake_settings.bake_image_clear, margin=self.bake_settings.bake_margin)
|
|
|
|
if channel == "COLOR":
|
|
print("Baking Color Pass")
|
|
self.C.scene.cycles.samples = 1
|
|
self.O.object.bake(type="DIFFUSE", pass_filter={'COLOR'}, use_clear=self.bake_settings.bake_image_clear, margin=self.bake_settings.bake_margin)
|
|
|
|
if channel == "AO":
|
|
if not denoise:
|
|
self.O.object.bake('INVOKE_DEFAULT',type="AO", use_clear=self.bake_settings.bake_image_clear, margin=self.bake_settings.bake_margin)
|
|
else:
|
|
self.O.object.bake(type="AO", use_clear=self.bake_settings.bake_image_clear, margin=self.bake_settings.bake_margin)
|
|
|
|
if channel == "NOISY":
|
|
print("Baking Diffuse Pass")
|
|
if not denoise:
|
|
self.O.object.bake('INVOKE_DEFAULT',type="DIFFUSE", pass_filter={'DIRECT', 'INDIRECT'}, use_clear=self.bake_settings.bake_image_clear, margin=self.bake_settings.bake_margin)
|
|
else:
|
|
self.O.object.bake(type="DIFFUSE", pass_filter={'DIRECT', 'INDIRECT'}, use_clear=self.bake_settings.bake_image_clear, margin=self.bake_settings.bake_margin)
|
|
|
|
return image
|
|
|
|
def denoise(self):
|
|
# denoise
|
|
if self.bake_settings.lightmap_bake:
|
|
denoised_image_path = node_functions.comp_ai_denoise(self.baked_images[0],self.baked_images[1],self.baked_images[2])
|
|
|
|
self.bake_image.filepath = denoised_image_path
|
|
self.bake_image.source = "FILE"
|
|
|
|
self.change_image_in_nodes(self.bake_image)
|
|
|
|
# blur
|
|
if self.bake_settings.ao_bake and self.bake_settings.denoise:
|
|
blur_image_path = node_functions.blur_bake_image(self.baked_images[0],self.baked_images[1])
|
|
self.bake_image.filepath = blur_image_path
|
|
self.bake_image.source = "FILE"
|
|
self.change_image_in_nodes(self.bake_image)
|
|
|
|
def add_lightmap_flag(self):
|
|
for obj in self.selected_objects:
|
|
obj.hasLightmap = True
|
|
|
|
def cleanup(self):
|
|
# set back engine
|
|
# self.C.scene.render.engine = self.render_engine
|
|
self.C.preferences.addons['cycles'].preferences.compute_device_type = self.cycles_device_type
|
|
|
|
# cleanup images
|
|
if self.bake_settings.cleanup_textures:
|
|
for img in self.D.images:
|
|
if self.bake_image.name in img.name and ("_COLOR" in img.name or "_NRM" in img.name or "_NOISY" in img.name) :
|
|
self.D.images.remove(img)
|
|
|
|
# show image
|
|
visibility_functions.show_image_in_image_editor(self.bake_image)
|
|
|
|
|
|
class PbrBakeUtilities(BakeUtilities):
|
|
active_material = None
|
|
parent_operator = None
|
|
|
|
def __init__(self,parent_operator,selected_objects, bake_settings):
|
|
super().__init__(parent_operator,selected_objects,bake_settings)
|
|
self.selected_materials = material_functions.get_selected_materials(selected_objects)
|
|
self.parent_operator = parent_operator
|
|
|
|
def ready_for_bake(self,material):
|
|
|
|
# check if not baked material
|
|
if "_Bake" in material.name:
|
|
print("Skipping cause already baked : " + material.name)
|
|
return False
|
|
|
|
print("\n Checking " + material.name + "\n")
|
|
|
|
# check if renderer not set to optix
|
|
self.setup_engine()
|
|
|
|
# check if selected to active is on
|
|
bpy.context.scene.render.bake.use_selected_to_active = False
|
|
|
|
# check if pbr node exists
|
|
check_ok = node_functions.check_pbr(self.parent_operator,material) and node_functions.check_is_org_material(self.parent_operator,material)
|
|
if not check_ok :
|
|
self.parent_operator.report({'INFO'}, "Material " + material.name + " has no PBR Node !")
|
|
return False
|
|
|
|
# copy texture nodes if they are linked multiple times
|
|
nodes = material.node_tree.nodes
|
|
image_textrure_nodes = node_functions.get_nodes_by_type(nodes,constants.Node_Types.image_texture)
|
|
for image_texture_node in image_textrure_nodes:
|
|
node_functions.remove_double_linking(material,image_texture_node)
|
|
return True
|
|
|
|
|
|
|
|
def bake_materials_on_object(self):
|
|
for material in self.selected_materials:
|
|
self.active_material = material
|
|
if not (self.ready_for_bake(material)):
|
|
continue
|
|
self.add_bake_plane()
|
|
self.bake_pbr()
|
|
self.create_pbr_bake_material("_Bake")
|
|
self.create_nodes_after_pbr_bake()
|
|
self.cleanup_nodes()
|
|
|
|
visibility_functions.switch_baked_material(True,"visible")
|
|
|
|
def add_bake_plane(self):
|
|
material = self.active_material
|
|
bake_plane = self.D.objects.get(material.name + "_Bake")
|
|
|
|
if bake_plane is not None:
|
|
self.parent_operator.report({'INFO'}, 'Delete Bake Plane')
|
|
return
|
|
|
|
self.O.mesh.primitive_plane_add(size=2, location=(2, 0, 0))
|
|
bake_plane = self.C.object
|
|
bake_plane.name = material.name + "_Bake"
|
|
bake_plane.data.materials.append(material)
|
|
|
|
|
|
def bake_pbr(self):
|
|
material = self.active_material
|
|
material.use_fake_user = True
|
|
|
|
nodes = material.node_tree.nodes
|
|
pbr_node = node_functions.get_pbr_node(material)
|
|
pbr_inputs = node_functions.get_pbr_inputs(pbr_node)
|
|
image_texture_node = None
|
|
|
|
# mute texture mapping
|
|
if self.bake_settings.mute_texture_nodes:
|
|
node_functions.mute_all_texture_mappings(material, True)
|
|
|
|
for pbr_input in pbr_inputs.values():
|
|
|
|
# -----------------------TESTING--------------------#
|
|
# skip if input has no connection
|
|
if not pbr_input.is_linked:
|
|
continue
|
|
|
|
# -----------------------IMAGE --------------------#
|
|
|
|
image_name = material.name + "_" + pbr_input.name
|
|
|
|
# find image
|
|
bake_image = self.D.images.get(image_name)
|
|
|
|
# remove image
|
|
if bake_image is not None:
|
|
self.D.images.remove(bake_image)
|
|
|
|
bake_image = self.D.images.new(image_name, width=self.image_size[0], height=self.image_size[1])
|
|
bake_image.name = image_name
|
|
|
|
image_texture_node = node_functions.add_node(material,constants.Shader_Node_Types.image_texture,"PBR Bake")
|
|
|
|
image_texture_node.image = bake_image
|
|
nodes.active = image_texture_node
|
|
|
|
# -----------------------SET COLOR SPACE--------------------#
|
|
if pbr_input is not pbr_inputs["base_color_input"]:
|
|
bake_image.colorspace_settings.name = "Non-Color"
|
|
|
|
# -----------------------BAKING--------------------#
|
|
if pbr_input is pbr_inputs["normal_input"]:
|
|
node_functions.link_pbr_to_output(material, pbr_node)
|
|
self.O.object.bake(type="NORMAL", use_clear=True)
|
|
else:
|
|
node_functions.emission_setup(material, pbr_input.links[0].from_socket)
|
|
self.O.object.bake(type="EMIT", use_clear=True)
|
|
|
|
# unmute texture mappings
|
|
node_functions.mute_all_texture_mappings(material, False)
|
|
|
|
# delete plane
|
|
self.O.object.delete()
|
|
|
|
# cleanup nodes
|
|
node_functions.remove_node(material,"Emission Bake")
|
|
node_functions.remove_node(material,"PBR Bake")
|
|
node_functions.reconnect_PBR(material, pbr_node)
|
|
|
|
def create_pbr_bake_material(self,material_name_suffix):
|
|
|
|
# -----------------------CREATE MATERIAL--------------------#
|
|
org_material = self.active_material
|
|
bake_material_name = org_material.name + material_name_suffix
|
|
bake_material = bpy.data.materials.get(bake_material_name)
|
|
|
|
if bake_material is not None:
|
|
bpy.data.materials.remove(bake_material)
|
|
|
|
# and create new from org. material
|
|
bake_material = org_material.copy()
|
|
bake_material.name = bake_material_name
|
|
self.bake_material = bake_material
|
|
|
|
def create_nodes_after_pbr_bake(self):
|
|
# -----------------------SETUP VARS--------------------#
|
|
org_material = self.active_material
|
|
bake_material = self.bake_material
|
|
nodes = bake_material.node_tree.nodes
|
|
pbr_node = node_functions.get_pbr_node(bake_material)
|
|
pbr_inputs = node_functions.get_pbr_inputs(pbr_node)
|
|
|
|
for pbr_input in pbr_inputs.values():
|
|
|
|
if not pbr_input.is_linked:
|
|
continue
|
|
|
|
# -----------------------REPLACE IMAGE TEXTURES--------------------#
|
|
first_node_after_input = pbr_input.links[0].from_node
|
|
tex_node = node_functions.get_node_by_type_recusivly(bake_material,first_node_after_input,constants.Node_Types.image_texture,True)
|
|
|
|
bake_image_name = org_material.name + "_" + pbr_input.name
|
|
bake_image = self.D.images.get(bake_image_name)
|
|
|
|
# if no texture node found (baking procedural textures) add new one
|
|
if tex_node is None:
|
|
tex_node = node_functions.add_node(bake_material,constants.Shader_Node_Types.image_texture,bake_image_name)
|
|
|
|
# keep org image if nothing changed
|
|
if bake_image is None:
|
|
org_image = self.D.images.get(tex_node.image.org_image_name)
|
|
tex_node.image = org_image
|
|
else:
|
|
image_functions.save_image(bake_image)
|
|
tex_node.image = bake_image
|
|
|
|
# -----------------------LINKING--------------------#
|
|
if pbr_input is pbr_inputs["normal_input"]:
|
|
normal_node = first_node_after_input
|
|
normal_node.inputs["Strength"].default_value = 1
|
|
|
|
|
|
if normal_node.type == constants.Node_Types.bump_map:
|
|
bump_node = normal_node
|
|
normal_node = node_functions.add_node(bake_material,constants.Shader_Node_Types.normal,"Normal from Bump")
|
|
normal_node.location = bump_node.location
|
|
nodes.remove(bump_node)
|
|
|
|
node_functions.make_link(bake_material, tex_node.outputs[0], normal_node.inputs["Color"])
|
|
node_functions.make_link(bake_material, normal_node.outputs["Normal"], pbr_input)
|
|
else:
|
|
node_functions.make_link(bake_material,tex_node.outputs[0], pbr_input)
|
|
|
|
# -----------------------SET COLOR SPACE--------------------#
|
|
if pbr_input is not pbr_inputs["base_color_input"]:
|
|
tex_node.image.colorspace_settings.name = "Non-Color"
|
|
|
|
self.active_material = bake_material
|
|
return bake_material
|
|
|
|
def cleanup_nodes(self):
|
|
bake_material = self.active_material
|
|
node_functions.remove_unused_nodes(bake_material) |