# Baking Textures as Image Sequence by Script in Cycles

Related to this: Baking textures on headless machine (batch baking)

Is there a way to batch the baking of textures over all frames? I have an animation and since the light is changing at each frame, would like to bake out the texture of each frame into an image sequence.

1. I've set my render mode to cycles
2. I've added a Image Texture Node and have it set to image sequence
3. My UV is unwrapped to the image sequence

If I put this in console, I can bake one frame to the sequence:

bpy.data.objects["Cube"].select = True
bpy.context.scene.frame_current = 1
bpy.ops.object.bake(type='COMBINED')


Similarly, I can bake another frame:

bpy.data.objects["Cube"].select = True
bpy.context.scene.frame_current = 2
bpy.ops.object.bake(type='COMBINED')


However, when I try to put this in a for loop to bake multiple frames like this:

for i in range(1,30):
bpy.context.scene.frame_current = i
bpy.data.objects["Cube"].select = True
bpy.ops.object.bake(type='COMBINED')


It will only bake the texture of the first frame in the loop. It appears like it is looping through all the frames and it is baking them, but the images in those frames do not get updated once the script is finished. Any ideas on what is happening?

Since 'Animation Baking' is now officially supported by this Add-on (shipped with Blender by default), you can simply call bpy.ops.object.anim_bake_image() for a sequence:

import bpy

scn = bpy.context.scene
scn.animrenderbake_start = 3
scn.animrenderbake_end = 30
bpy.ops.object.anim_bake_image('INVOKE_DEFAULT')


The following script is a slightly modified version of the Add-on in order to bake specific frames (for demonstration purposes). To bake all frames (or a custom range) use the range() function.

import bpy
import os
import shutil

# set the frames to bake
bake_frames = [0, 230, 99]

# format frame number
def framefile(filepath, frame):
fn, ext = os.path.splitext(filepath)
return "%s_%04d%s" % (fn, frame, ext)

# scene attributes
context = bpy.context
is_cycles = (context.scene.render.engine == 'CYCLES')
selected = context.selected_objects
img = None

# inspect the materials
if is_cycles:
inactive = None
selected = None
for mat_slot in context.active_object.material_slots:
mat = mat_slot.material
if not mat or not mat.node_tree:
continue
trees = [mat.node_tree]
while trees and not img:
tree = trees.pop()
node = tree.nodes.active
if node.type in {'TEX_IMAGE', 'TEX_ENVIRONMENT'}:
img = node.image
break
for node in tree.nodes:
if node.type in {'TEX_IMAGE', 'TEX_ENVIRONMENT'} and node.image:
if node.select:
if not selected:
selected = node
else:
if not inactive:
inactive = node
elif node.type == 'GROUP':
if img:
break
if not img:
if selected:
img = selected.image
elif inactive:
img = inactive.image
else:
for uvtex in context.active_object.data.uv_textures:
if uvtex.active_render == True:
for uvdata in uvtex.data:
if uvdata.image is not None:
img = uvdata.image
break

# convert the path to absolute path
img_filepath_abs = bpy.path.abspath(img.filepath, library=img.library)

# iterate through the frame list
for f in bake_frames:
print("Baking frame %d" % f)

# set the frame
context.scene.frame_set(f)

# cycles bake
if is_cycles:
bpy.ops.object.bake()

# internal bake
else:
bpy.ops.object.bake_image()

# save the image
img.save()
img_filepath_new = framefile(img_filepath_abs, f)

# copy the image
shutil.copyfile(img_filepath_abs, img_filepath_new)
print("Saved %r" % img_filepath_new)

• How to make it work with image selection? If I use images without sequence it just bakes the first frame. Jan 3, 2018 at 16:37
• Don't get it, sorry @Denis. The addon basically bakes an image for every frame in the timeline (per object), so what do you mean by images without a sequence? Can you elaborate on what are you trying to do?
– p2or
Jan 3, 2018 at 17:24
• I have images that are named differently without suffixes 001 002 etc.., so if I load them as a sequence only the first image is baked since the next image has a different name. Jan 3, 2018 at 17:27
• And those images you'd like to plug into a shader via Image Texture node to get another image every frame, right? If yes, I think that's not supported, the node only accepts a sequence. Why you can't just rename the images into a real sequence with any batch-rename tool like MuCommander or even TotalCommander? Otherwise you need to tell blender which image to load at frame X or frame Y into the node via scripting and some handler or something. I think that isn't really worth it @Denis
– p2or
Jan 3, 2018 at 17:55
• Had a bit time today and converted that into a real addon, which you can find here. Once it's enabled, you'll find a new panel in the misc area of the node editor's tool shelf, if you select any Image Texture node: i.stack.imgur.com/QiuDN.jpg In case you want to get the same output file names after baking, we need to modify the other addon. Hope that helps, any feedback is appreciated @Denis
– p2or
Jan 4, 2018 at 19:47