Skip to content

Batch Rendering Models with Blender

In this article, I’ll explain how to use Blender 4.0 to create renders of multiple models using Blender scripting. I’ll be using Kenney’s Hexagon Kit as the 3D assets, and rendering one image per model with one click of a button.

  1. Start by opening a new Blender project and importing all the models you want to render. In my case, I imported the GLB models.

  2. Move all the models into one Collection so we can find them easily later. Rename the collection to something memorable - you will use this name later.

  3. At this point, you can set up any lighting and reposition any of the models.

  4. Set up the camera.

    1. Position: The easiest way I found was to position the editor view in the correct position, and then use View > Align View > Align Active Camera To View.

    2. Render Size: Select any object in the scene. Select the Output tab in the Properties area, and change the dimensions of the output images here.

      A screenshot of Blender's Properties panel with the Output tab selected. Under 'Format', the tab contains options labelled 'Resolution X' and 'Y', which are the relevant options to change here

  5. Check the results of the render using this menu option:

    A screenshot of Blender's Render menu, with the Render Image option highlighted

    You may want to only render one object when testing the final result. Toggle off other objects using the camera icon in the Outliner area:

    A screenshot of Blender's Outliner area, showing two objects. There is a camera icon to the right of each object's name, highlighted with a pink outline to indicate that these icons are relevant to this step: one icon is active, and one is inactive - shown with a cross in the camera icon.

  6. Once you’re happy with the render result, switch to the Scripting layout using the top bar and make a new script. Make sure you save your new file with the .py extension: Blender will not do this for you automatically.

batch_render_models.py
import bpy, os
def set_render_self_and_children(object, show):
object.hide_render = not show
for child in object.children:
child.hide_render = not show
dir_path = '/full/path/to/desired/output/directory'
objects_to_render = list(bpy.data.collections["YourCollectionNameHere"].all_objects)
for object in objects_to_render:
set_render_self_and_children(object, True)
for other in objects_to_render:
if object == other:
continue
set_render_self_and_children(other, False)
bpy.context.scene.render.filepath = os.path.join(dir_path, object.name + '.png')
bpy.ops.render.render(animation=False, write_still=True)
import bpy, os
  • Importing Blender’s Python module, as well as the os module to use in file path manipulation
def set_render_self_and_children(object, show):
object.hide_render = not show
for child in object.children:
child.hide_render = not show
  • Defining a function with two parameters: an object in Blender, and a bool value indicating whether it should be rendered
  • Setting the object’s hide_render value to the inverse of the show argument
  • Iterating through the object’s immediate children and setting their hide_render values to the same; if your models have more complex structures, you may want to modify this to iterate through more than one level of children
objects_to_render = list(bpy.data.collections["YourCollectionNameHere"].all_objects)
for object in objects_to_render:
  • Using Blender’s API to access all objects in the collection created during the setup, and putting those objects into a list
  • Iterating over the list; then, for each object in the list:
set_render_self_and_children(object, True)
for other in objects_to_render:
if object == other:
continue
set_render_self_and_children(other, False)
bpy.context.scene.render.filepath = os.path.join(dir_path, object.name + '.png')
bpy.ops.render.render(animation=False, write_still=True)
  • First, enabling rendering for this object using the function defined above
set_render_self_and_children(object, True)
for other in objects_to_render:
if object == other:
continue
set_render_self_and_children(other, False)
bpy.context.scene.render.filepath = os.path.join(dir_path, object.name + '.png')
bpy.ops.render.render(animation=False, write_still=True)
  • Turning off rendering for all objects except the one we’re currently looking at. In detail:
    • Iterating over the list of objects again
    • Doing nothing if we find the object we’re looking at in the outer loop
    • Otherwise, preventing the object from rendering with the function defined above
set_render_self_and_children(object, True)
for other in objects_to_render:
if object == other:
continue
set_render_self_and_children(other, False)
bpy.context.scene.render.filepath = os.path.join(dir_path, object.name + '.png')
bpy.ops.render.render(animation=False, write_still=True)
  • Setting Blender’s internal render filepath value to the target directory plus the model’s name and PNG extension
  • Note that (unintuitively) you don’t pass an output path into the render function, the output path is set here completely separately
set_render_self_and_children(object, True)
for other in objects_to_render:
if object == other:
continue
set_render_self_and_children(other, False)
bpy.context.scene.render.filepath = os.path.join(dir_path, object.name + '.png')
bpy.ops.render.render(animation=False, write_still=True)
  • Calling Blender’s render function
  • Ensuring that the rendering process doesn’t pull data from the animation ranges in the scene by setting animation to False
  • Setting write_still to True so that the render writes to an external file at the path set earlier

 

A screenshot from Blender's 3D viewport showing a lot of grey models all in the same place and merged together

Before

A screenshot of a grid of files with thumbnails, each thumbnail showing a different render of a textured model, and each file named according to the name of the model

After