# Get image pixels from multiple viewer nodes

For Blender 2.81 and Cycles render.

I want to access all of the following data passes from a Python script:

• Z
• Normal
• Vector
• Object Index

Therefore, I created three Viewer Nodes with different names. See the following image:

The viewer node on the top is getting both the Z and the Normal passes. The one in the middle is getting the Vector, and the one in the bottom the IndexOB.

Now my issue is that when I use the following code pixels = bpy.data.images['Viewer Node'].pixels, I can only access the data from the top Viewer Node (we only get the pixel data of the node that was selected from the user interface).

Is there a way that I can specify through the NameId of the Viewer Node which pixels data do I want to access?

I tried selecting and activating the different nodes through a script but apparently the data does not get automatically updated. The viewer node has to be manually clicked to make it visually active which then updates the images['Viewer Node'] data that we want to access. I found more info about this "known limitation" here.

• similar question: blender.stackexchange.com/questions/32640/… Jan 20, 2020 at 21:55
• Can you try to use one Viewer with Switch nodes or connect sockets via python for every case? Jan 24, 2020 at 15:41
• Tried switch nodes and the issue is the same. To connect via python for every case I would need to render multiple times. I want to render only once. Jan 24, 2020 at 15:55
• Is there any reason why you can't use the File Output nodes? Jan 29, 2020 at 18:50
• I believe that you could combine the images in a specific way and recover the originals at the cost of bit depth. You have 128 bits per pixel from the viewer node (32 bits * 4 channels). For Z(1 channel) + norm(3) + vec(3) + index(1), you would need 8 channels giving you 16 bits per channel (128/8 = 16). Not sure exactly how to carry it out though since the values are floating-point. Jan 5, 2021 at 4:52

Here is a workaround that will do the job in some cases:

Instead of multiple Viewer nodes use a single Viewer node and a switch to change the image input that the Viewer gets. For Example:

Old system with multiple Viewer nodes:

New system with one Viewer node and a switch:

The switch can be toggled in python using the following command:

bpy.context.scene.node_tree.nodes["Switch"].check = False


If you need more than two rendering configurations (i.e. more than two Viewer nodes in the old system) you can use an array of Switch nodes:

Here is how to control the three Switch nodes in python, assuming you don't gives them custom names:

bpy.context.scene.node_tree.nodes["Switch"].check = False        # first Switch
bpy.context.scene.node_tree.nodes["Switch.001"].check = False    # second Switch
bpy.context.scene.node_tree.nodes["Switch.002"].check = False    # third Switch


Although this won't solve the problem in the original at the time of writing almost two years old question, I hope it will provide a solution to other people like me stumbling across this thread in search of answers.