2

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 6404804 = 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 simple (I am a beginner to Blender after all) but I cannot determine what?

Note: I am aware that --background could have something to do with it, but I am unable to disable that option, because doing so introduces a whole range of RuntimeError: Operator bpy.ops.wm.append.poll() failed, context is incorrect errors all over the place in my other script, which I have no idea how to fix. So I guess this question is essentially how to force the viewer node to update when running Blender in the background.

aviator
  • 131
  • 6

1 Answers1

1

Solved -- my problem was actually related to Blender's hard-coded behavior in background mode, rather than to something going wrong with the render process itself. In order to get the Viewer Node to work in background mode, you need to modify some source code and recompile Blender as described in the link, because it is disabled by default for optimization reasons. Then run:

path\to\recompiled\blender --background --python my_render_script.py
aviator
  • 131
  • 6