2
$\begingroup$

When I Bake my object it gets slightly darker with each bake. So when you start with white it eventually becomes gray and then dark until it's black. Is it maybe lighting that causes this? But I am only baking Diffuse color without direct/indirect lights. What gives? Is this a side effect or bug in baking or am I missing a setting? I am using these bake settings:

s = bpy.context.scene
s.cycles.device = 'GPU'
s.render.engine = 'CYCLES'
s.cycles.use_adaptive_sampling = False
s.cycles.samples = 1
s.cycles.bake_type = 'DIFFUSE'
s.render.bake.use_pass_direct = False
s.render.bake.use_pass_indirect = False
s.render.bake.margin = 0
s.cycles.use_denoising = False

enter image description here

I created a script that reproduces this problem. Just create a cube with 1 material and make it white. Then select and and keep running this script. Be careful sometimes Blender is bugged and crashes with too many runs.

import bpy

class BakeTest:
    def __init__(self) -> None:
        self.context = bpy.context
        self.data = bpy.data
        self.bake_image = None
        self.prev_uvmap_names = None

    def set_object_selected(self, obj, select):
        obj.select_set(select)
        self.context.view_layer.objects.active = obj if select else None

    def bake(self, obj):
        self.bake_images = []
        self.add_image_texture_for_baking(obj)
        self.prev_uvmap_names = [uv_layer.name for uv_layer in obj.data.uv_layers]
        self.create_uv_map_and_unwrap(obj)

        bpy.ops.object.bake(type='DIFFUSE')

        for uvname in self.prev_uvmap_names:
            obj.data.uv_layers.remove(obj.data.uv_layers[uvname])
        
        self.setup_new_material_with_baked_texture(obj)

    def add_image_texture_for_baking(self, obj):
        D = self.data
        self.bake_image = D.images.new(f"Image.{obj.name}", 1, 1)
        print(f"Created temporary bake image: {self.bake_image}")
        mat = obj.material_slots[0].material
        nodes = mat.node_tree.nodes
        for n in nodes:
            n.select = False
        tex_node = nodes.new(type='ShaderNodeTexImage')
        tex_node.image = self.bake_image
        tex_node.name = mat.name
        tex_node.select = True
        nodes.active = tex_node

    def create_uv_map_and_unwrap(self, obj):
        uvmap = obj.data.uv_layers.new(name="UVMapFinal")
        idx = obj.data.uv_layers.active_index = obj.data.uv_layers.find(uvmap.name)
        obj.data.uv_layers[idx].active = True
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=0)
        bpy.ops.object.mode_set(mode='OBJECT')

    def setup_new_material_with_baked_texture(self, obj):
        D = self.data
        obj.data.materials.clear()
        mat = D.materials.new(name="NewBakeMaterial")
        obj.data.materials.append(mat)
        mat.use_nodes = True
        nodes = mat.node_tree.nodes
        tex_node = nodes.new(type='ShaderNodeTexImage')
        tex_node.image = self.bake_image
        tex_node.location = (-300,200)
        mat.node_tree.links.new(tex_node.outputs['Color'], nodes['Principled BSDF'].inputs['Base Color'])
        uvmap_node = nodes.new(type='ShaderNodeUVMap')
        uvmap_node.uv_map = obj.data.uv_layers[0].name
        uvmap_node.location = (-500,200)
        mat.node_tree.links.new(uvmap_node.outputs['UV'], tex_node.inputs['Vector'])


s = bpy.context.scene
s.cycles.device = 'GPU'
s.render.engine = 'CYCLES'
s.cycles.use_adaptive_sampling = False
s.cycles.samples = 1
s.cycles.bake_type = 'DIFFUSE'
s.render.bake.use_pass_direct = False
s.render.bake.use_pass_indirect = False
s.render.bake.margin = 0
s.cycles.use_denoising = False

b = BakeTest()
b.bake(bpy.context.active_object)
$\endgroup$
1
  • $\begingroup$ yes, it's a bug $\endgroup$
    – Karan
    Commented Apr 2 at 5:01

1 Answer 1

-1
$\begingroup$

you should use bake_type = "EMIT" with color management > View Transform > Standard

import bpy

class BakeTest:
    def __init__(self) -> None:
        self.context = bpy.context
        self.data = bpy.data
        self.bake_image = None
        self.prev_uvmap_names = None

    def set_object_selected(self, obj, select):
        obj.select_set(select)
        self.context.view_layer.objects.active = obj if select else None

    def bake(self, obj):
        self.bake_images = []
        self.add_image_texture_for_baking(obj)
        self.prev_uvmap_names = [uv_layer.name for uv_layer in obj.data.uv_layers]
        self.create_uv_map_and_unwrap(obj)

        bpy.ops.object.bake(type='EMIT')

        for uvname in self.prev_uvmap_names:
            obj.data.uv_layers.remove(obj.data.uv_layers[uvname])
        
        self.setup_new_material_with_baked_texture(obj)

    def add_image_texture_for_baking(self, obj):
        D = self.data
        self.bake_image = D.images.new(f"Image.{obj.name}", 1, 1)
        print(f"Created temporary bake image: {self.bake_image}")
        mat = obj.material_slots[0].material
        nodes = mat.node_tree.nodes
        for n in nodes:
            n.select = False
        tex_node = nodes.new(type='ShaderNodeTexImage')
        tex_node.image = self.bake_image
        tex_node.name = mat.name
        tex_node.select = True
        nodes.active = tex_node

    def create_uv_map_and_unwrap(self, obj):
        uvmap = obj.data.uv_layers.new(name="UVMapFinal")
        idx = obj.data.uv_layers.active_index = obj.data.uv_layers.find(uvmap.name)
        obj.data.uv_layers[idx].active = True
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=0)
        bpy.ops.object.mode_set(mode='OBJECT')

    def setup_new_material_with_baked_texture(self, obj):
        D = self.data
        obj.data.materials.clear()
        mat = D.materials.new(name="NewBakeMaterial")
        obj.data.materials.append(mat)
        mat.use_nodes = True
        nodes = mat.node_tree.nodes
        tex_node = nodes.new(type='ShaderNodeTexImage')
        tex_node.image = self.bake_image
        tex_node.location = (-300,200)
        mat.node_tree.links.new(tex_node.outputs['Color'], nodes['Principled BSDF'].inputs['Emission Color'])
        nodes['Principled BSDF'].inputs['Emission Strength'].default_value = 1.0
        uvmap_node = nodes.new(type='ShaderNodeUVMap')
        uvmap_node.uv_map = obj.data.uv_layers[0].name
        uvmap_node.location = (-500,200)
        mat.node_tree.links.new(uvmap_node.outputs['UV'], tex_node.inputs['Vector'])


s = bpy.context.scene
s.cycles.device = 'GPU'
s.render.engine = 'CYCLES'
s.cycles.use_adaptive_sampling = False
s.cycles.samples = 1
#s.cycles.bake_type = 'DIFFUSE'
#s.render.bake.use_pass_direct = False
#s.render.bake.use_pass_indirect = False
s.render.bake.margin = 0
s.cycles.use_denoising = False

b = BakeTest()

for _ in range(50):
    b.bake(bpy.context.active_object)
$\endgroup$
1
  • $\begingroup$ That doesn't work. The texture baked is black. $\endgroup$
    – Megan Love
    Commented Apr 3 at 2:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .