[PYTHON] Try adding a simple image baking function as an add-on

Posted as the 23rd of Blender Advent Calendar 2020. https://qiita.com/advent-calendar/2020/blender

To create textures for game models and VRchat avatars Is there a purpose to bake textures made with shaders or to bake images with UVs organized? I think we've been seeing more and more talk about texture baking in Blender since spring.

I also encountered a case where I needed to prepare a bake image with the touch of a button in a certain job. I have created an add-on to create the desired bake image.

Use the currently active UV for the image displayed in the image editor Bake the diffuse color.

ySympleBekeImage.py


import bpy
bl_info = {
    "name": "Simple Bake Image",
    "description": "Bake the color of the object in the image displayed in the UV editor",
    "author": "Yukimi",
    "version": (0,9),
    "blender": (2, 80, 0),
    "location": "material",
    "warning": "",
    "wiki_url": "",
    "tracker_url": "http://yukimi-blend.blogspot.jp/",
    "category": "material"}


#Creating a node for baking
def criete_bake_terget(mat, image, uv_layer):
    node_tree = mat.node_tree
    img_node = node_tree.nodes.new("ShaderNodeTexImage")
    img_node.image = image
    uv_node = node_tree.nodes.new("ShaderNodeUVMap")
    uv_node.uv_map = uv_layer.name
    node_tree.links.new( uv_node.outputs[0], img_node.inputs[0] )
    #Bake target is the active node
    node_tree.nodes.active = img_node
    return(img_node, uv_node)
#Erasing baking material
def crean_beke_terget(beke_nodes):
    for m in beke_nodes:
        mat = m[0]
        img_node = m[1][0]
        uv_node = m[1][1]
        mat.node_tree.nodes.remove(img_node)
        mat.node_tree.nodes.remove(uv_node)
#Bake
def Simple_bake(scene):
    #Save current render settings
    ref_engine = scene.render.engine
    scene.render.engine = 'CYCLES'
    #Save the current number of samples
    ref_sampkung = scene.cycles.samples
    scene.cycles.samples = 8
    #Bake operation
    bpy.ops.object.bake(type='DIFFUSE', pass_filter={'COLOR',}, use_clear=False)
    #Comment out here if you want to use the output of the radiant node
    #bpy.ops.object.bake(type='EMIT', use_clear=False)
    #Based on the number of samples
    scene.cycles.samples = ref_sampkung
    #Based on the rendering engine
    scene.render.engine = ref_engine

def bake_func(context):
    scene = context.scene
    obj = bpy.context.active_object
    #Is the active object a mesh?
    if obj.type != "MESH": return()
    if context.space_data.mode != 'UV': return()
    #Get the image displayed in the view
    image = context.space_data.image
    #UV acquisition
    uv_layer = obj.data.uv_layers[obj.data.uv_layers.active_index]
    #Loop on individual materials
    #(If there are multiple materials, it is necessary to set a node for baking for each)
    bake_nodes = []
    for slot in  obj.material_slots:
        mat = slot.material
        nodes = criete_bake_terget(mat, image, uv_layer)
        bake_nodes.append([mat,nodes])
    #Bake only diffuse color
    Simple_bake(scene)
    #Clean up the node used for baking
    crean_beke_terget(bake_nodes)
    
    
###################################################
class bake_OT_diffusecolor(bpy.types.Operator):
	'''bake diffuse coor to display Image'''
	bl_idname = "action.bake_diffuse"
	bl_label = "bake diffuse coor to display Image"
	def execute(self, context):
		bake_func(context)
		return {'FINISHED'}


def menu_func(self, context):
	self.layout.operator("action.bake_diffuse", 
		text="Show color Bake on image" )

def register():
    bpy.utils.register_class(bake_OT_diffusecolor)
    bpy.types.IMAGE_MT_image.prepend(menu_func)

def unregister():
    bpy.types.IMAGE_MT_image.remove(menu_func)
    bpy.utils.unregister_class(bake_OT_diffusecolor)

if __name__ == "__main__":
    register()
##########################################################

When installed, the item "Display color and bake on image" will be added to the image menu. image.png

If you just want to bake, you can use the bake function etc. in TexTools. It cannot be used for work such as combining images of materials of multiple objects. The work of specifying UV and specifying the bake target is complicated, isn't it?

By rewriting the Simple_bake function, I think it can be used to output an image that suits the site. This time, only the diffuse color is used, so the baking speed is increased by lowering the number of samplings. Also, the existing image is not cleared in case of adjusting the bake across multiple objects.

I hope it helps.

Recommended Posts

Try adding a simple image baking function as an add-on
[Python] I made an image viewer with a simple sorting function.
A simple difference when passing a pointer as a function argument
Try creating a CRUD function
Understand the function of convolution using image processing as an example
Try to extract a character string from an image with Python3
Utilization of lambda (when passing a function as an argument of another function)
Convert a string to an image
The eval () function that calculates a string as an expression in python
Try drawing a simple animation in Python
Try to generate an image with aliasing