Based on this answer, I am trying to extract the per-frame RGB and depth arrays of some animation scene.
However, the compositor render layer and viewer node setup that I am programmatically building does not appear to work. I am connecting 2 outputs of the render layer to 2 inputs of the viewer node, but any call to render()
does not actually change or update the pixels
field of the viewer node -- the render process itself works (for example, it shows stuff when storing to an output file), nothing happens in the context of the compositor. All output values are always zero.
In fact, even the size/shape of pixels
is incorrect (262144) and does not depend on whatever input resolution I pass to the render engine.
Here is a minimal example to reproduce the problem:
import bpy
import numpy as np
width = 640
height = 480
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.render.resolution_x = width
bpy.context.scene.render.resolution_y = height
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.render.use_compositing = True
bpy.context.scene.use_nodes = True
tree = bpy.context.scene.node_tree
links = tree.links
for n in tree.nodes:
tree.nodes.remove(n)
rl = tree.nodes.new('CompositorNodeRLayers')
vl = tree.nodes.new('CompositorNodeViewer')
vl.use_alpha = True
links.new(rl.outputs[0], vl.inputs[0]) # link Renger Image to Viewer Image
links.new(rl.outputs[2], vl.inputs[1]) # link Render Z to Viewer Alpha
# Render
bpy.ops.render.render()
# Get the pixels and put them into a numpy array
pixels = np.array(bpy.data.images['Viewer Node'].pixels)
print(len(pixels))
width = bpy.context.scene.render.resolution_x
height = bpy.context.scene.render.resolution_y
# Reshaping into image array 4 channel (rgbz)
print('pixels:', pixels.shape) # (262144, ) even though 640*480*4 = 1228800
print('values:', np.min(pixels), np.max(pixels)) # 0.0, 0.0
image = pixels.reshape((height, width, 4)) # Error
I am using Blender 2.83.6 LTS, and am running this command to execute the script:
blender --background --python .\minimal_blender.py
I feel like I am overlooking something very simple (I am a beginner to Blender after all) but I cannot determine what?