1

I know how to render one image via Python and get an output with Blender's compositor.

What if I need it to render 100 images for me with numerical names e.g: img_1, img_2, img_3 etc.?

Give me please an example of a working script via Ubuntu terminal and Python sys.argv?

Can I for example setup compositor nodes, and then simply render scene and get composited render as a result render?

Python code for rendering 1 image:

import bpy
import sys

argv = sys.argv
argv = argv[argv.index("--") + 1:]

current_frame_path = argv[0]
print(argv)
ob = bpy.context.active_object
scene_rd = bpy.context.scene.render

scene_rd.filepath = current_frame_path
bpy.ops.render.render(write_still=True)

Shell script for rendering n images

#!/bin/bash

imgs_cnt=n

output_frame_path='RenderedImages/img'


for (( i=1; i<=imgs_cnt; i++ )); do
  echo "Rendering frame ${i}/${imgs_cnt}..."

  (
    cd /path/to/model/
blender --background Model.blend --python Render.py-- "${output_img_path}/img_${i}.png"
  )

  echo "Image ${i}/${imgs_cnt} has been rendered"
done

Here's an example for what I'm trying to do:

This is an automatically generated scene with plants, and I render it via executing shell script in terminal. It use 3 python scripts for blender. 1st script is for generating the scene, it places objects on the scene with different location and rotation settings and check if objects are intersected (to avoid clipping). 2nd script is for rendering scene. 3rd script isn't yet ready but it will be generating a mask for generated scene via cryptomatte. As a final result I want blender to output me 2 images into 2 different directories. 1st for the original images and 2nd for mask annotations. enter image description here enter image description here

cxnt
  • 397
  • 1
  • 5
  • 27
  • 3
    Hi. I suggest showing the relevant code you have for rendering 1 image. The last sentence comes across a little demanding and probably won't go down well with other users. – Ray Mairlot Feb 17 '20 at 15:47
  • @RayMairlot here you go – cxnt Feb 18 '20 at 06:35
  • No extra args needed here blender -b -f ${i} -o "${output_img_path}/img_###.png" When useing -- make sure it is clearly separated by spaces. See https://blender.stackexchange.com/questions/6817/how-to-pass-command-line-arguments-to-a-blender-python-script Would be a lot quicker to copy images from one render than to render each. – batFINGER Feb 18 '20 at 06:49
  • @batFINGER I use args because I render an original image, then a grayscale mask for it, and output them to different directories. My question is how to do the same, but when using compositor? I need an original scene render and cryptomatte image outputs – cxnt Feb 18 '20 at 08:00
  • @batFINGER Can I for example setup a compositor nodes, and then simply render scene and get compositorED render as a result render? – cxnt Feb 18 '20 at 08:26

1 Answers1

3

You can add File Output nodes to the compositor to get multiple files saved from any point of your compositing without the need for any Python:

enter image description here

You can also use Python to add more nodes:

import bpy

bpy.context.scene.use_nodes = True
tree = bpy.context.scene.node_tree


for every_node in tree.nodes:
    tree.nodes.remove(every_node)

RenderLayers_node = tree.nodes.new('CompositorNodeRLayers')   
RenderLayers_node.location = 0,0

comp_node = tree.nodes.new('CompositorNodeComposite')   
comp_node.location = 400,0

links = tree.links
link = links.new(RenderLayers_node.outputs[0], comp_node.inputs[0])

for i in range(0,100):
    output_node = tree.nodes.new(type='CompositorNodeOutputFile')
    output_node.name = "Output node number "+str(i+1)
    output_node.location = (400,(-140-i*110)) 
    link = links.new(RenderLayers_node.outputs[0], output_node.inputs[0])

See the documentation for more info.

Martynas Žiemys
  • 24,274
  • 2
  • 34
  • 77
  • That's now gonna work. What if I need to render 1000 images? I need to script it anyway – cxnt Feb 18 '20 at 09:39
  • Fix typo: NOT* gonna work – cxnt Feb 18 '20 at 10:07
  • Sorry, my bad, did not read the question carefully enough. See the update. – Martynas Žiemys Feb 18 '20 at 11:24
  • Thanks for the effort, appreciated your time. I updated the question with more detailed info of what I'm trying to achieve. Your answer kinda answers the question "How to render multiple images via compositor?" but that's not in the way I meant it – cxnt Feb 18 '20 at 11:51
  • 1
    You might not be using Cryptomatte the way it is intended to be used if you are outputting the colourful image. Generally you should not see it ever. You should save Cryptomatte masks using EXR format with the rendered image or as separate greyscale masks using Cryptomatte nodes to generate them. https://www.exr-io.com/ might also be of interest... – Martynas Žiemys Feb 18 '20 at 12:00
  • Oh, no, wait, you have to see the image, but only for choosing what masks to generate :), anyway, it would defeat the purpose of Crytomatte if it was used for masks. You would have serious problems with the edges of the masks. – Martynas Žiemys Feb 18 '20 at 12:09
  • I need a colorful mask to convert pixel coords of each object on the scene to json format. As for my question, I'll figure it out from here, thanks for the tips. It would be ideal if I could output original scene in 1 dir, grayscale in 2nd dit, and colorful mask in 3rd dir. – cxnt Feb 18 '20 at 12:10
  • Yeh, blender viewer and .exr file output have color differences – cxnt Feb 18 '20 at 12:11
  • It should be fairly straight forward to set the output directories, just change the parameters of the output nodes. In my example that could be something like output_node.base_path = "C:\\Render\\SomeDirectory\\" I will not attempt to provide the full solution because I might not know the full context, I think it will be easier for you to know what exactly you need. – Martynas Žiemys Feb 18 '20 at 12:30
  • If you simply set path to output file node, it will overwrite image after each render, cause you can't iterate names via nodes – cxnt Feb 18 '20 at 12:34