0
$\begingroup$

I am writing a script to automat baking in blender for my objects. I want similar thing like n Unity3D, I have objects (lights, area lights, reflection probes, meshes) in my blender I want Bake light maps Then store the baked texture in output directory

def bake_logic2(bl_path: BlenderPath) -> BLEND_RESP:
    # Select all objects in the scene (including sub children)
    bpy.ops.object.select_all(action='DESELECT')
    bpy.ops.object.select_by_type(type='MESH')
    bpy.ops.object.select_hierarchy(direction='CHILD', extend=True)

    selected_objects = bpy.context.selected_objects

    # List to store objects with materials
    objects_to_bake = []

    # Iterate through the selected objects
    for obj in selected_objects:
        # Check if the object has materials
        if obj.type == 'MESH' and obj.data.materials:
            objects_to_bake.append(obj)

    # Check if there are any objects to bake
    if not objects_to_bake:
        return False, "No objects with materials found in the scene."

    # Set up the bake context
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.scene.cycles.device = 'GPU'

    # Iterate through the objects to bake
    for obj in objects_to_bake:
        # Select the object to bake
        bpy.ops.object.select_all(action='DESELECT')
        obj.select_set(True)
        bpy.context.view_layer.objects.active = obj

        # Create a new image for baking
        image_name = f"{obj.name}_bake.png"
        image = bpy.data.images.new(image_name, width=1024, height=1024, alpha=True)
        obj.data.uv_layers.new(name="BakeUVMap")

        # Assign the new image to the material(s)
        for material_slot in obj.material_slots:
            material_slot.material.use_nodes = True
            node_tree = material_slot.material.node_tree

            # Check if "Image Texture" node exists
            if 'Image Texture' in node_tree.nodes:
                image_texture_node = node_tree.nodes['Image Texture']
                image_texture_node.image = image

        # Bake the object
        bpy.ops.object.bake(type='DIFFUSE')

        # Save the baked result externally
        image_filepath = os.path.join(bl_path.outPath, image_name)
        image.filepath_raw = image_filepath
        image.save()

But unfortunately after trying so much, the output images are black. Also I think I am missing lights and probes effect

enter image description here

$\endgroup$
7
  • $\begingroup$ If the Metallic socket of Principled BSDF node is connected then disconnect it and set the value to 0 $\endgroup$
    – Karan
    Commented Jul 8, 2023 at 9:11
  • $\begingroup$ I did same thing but still it is black $\endgroup$
    – USMANHEART
    Commented Jul 8, 2023 at 15:47
  • $\begingroup$ try bpy.ops.object.bake('INVOKE_DEFAULT', type='DIFFUSE', pass_filter={'COLOR'}) $\endgroup$
    – Karan
    Commented Jul 8, 2023 at 16:00
  • $\begingroup$ After adding this line, it is still dark $\endgroup$
    – USMANHEART
    Commented Jul 8, 2023 at 16:57
  • $\begingroup$ What is bl_path: BlenderPath? please provide the complete code so that I can run it. $\endgroup$
    – Karan
    Commented Jul 8, 2023 at 17:02

1 Answer 1

1
$\begingroup$

Not a perfect answer but hope it will guide you.

In your code you have to select the image_texture_node and make it active.

image_texture_node = node_tree.nodes['Image Texture']
image_texture_node.image = image
image_texture_node.select = True
node_tree.nodes.active = image_texture_node
import bpy
from bpy import context
import os


def bake(path: str, size: int=1024):
    context.scene.render.engine = 'CYCLES'
    context.scene.cycles.device = 'GPU'

    for object in context.selected_objects:
        if object.type != 'MESH':
            continue

        # create new image to bake on
        image = bpy.data.images.get(f"{object.name}_bake")
        if not image:
            image = bpy.data.images.new(f"{object.name}_bake", width=size, height=size, alpha=True)

        if object.material_slots:
            for slot in object.material_slots:
                if slot.material and slot.material.use_nodes:
                    node_tree = slot.material.node_tree

                    # create image texture node
                    node = node_tree.nodes.get(image.name)
                    if not node:
                        node = node_tree.nodes.new(type='ShaderNodeTexImage')
                        node.name = image.name
                    node.image = image
                    node.select = True
                    node_tree.nodes.active = node

        override = context.copy()
        override['selected_objects'] = [object]
        bpy.ops.object.bake(override, type='COMBINED', pass_filter={'DIRECT', 'INDIRECT', 'DIFFUSE'})

        # Save the baked result externally
        filepath = os.path.join(path, f"{image.name}.png")
        image.filepath_raw = filepath
        image.save()


bake(path='C:/Users/karan/Desktop/', size=1024)
$\endgroup$

You must log in to answer this question.

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