Die Ausgabe des Compositor Viewer-Knotens wird beim Rendern über ein Python-Skript nie aktualisiert

Sep 22 2020

Basierend auf dieser Antwort versuche ich, die RGB- und Tiefenarrays pro Bild einer Animationsszene zu extrahieren. Das von mir programmgesteuert erstellte Compositor-Render-Layer und der Viewer-Knoten-Setup scheinen jedoch nicht zu funktionieren. Ich verbinde 2 Ausgänge der Renderebene mit 2 Eingängen des Viewer-Knotens, aber jeder Aufruf von render()ändert oder aktualisiert das pixelsFeld des Viewer-Knotens nicht - der Renderprozess selbst funktioniert (zum Beispiel zeigt er Dinge beim Speichern in eine Ausgabedatei), passiert nichts im Kontext des Compositors. Alle Ausgabewerte sind immer Null.

Tatsächlich ist sogar die Größe / Form von pixelsfalsch (262144) und hängt nicht von der Eingabeauflösung ab, die ich an die Render-Engine übergebe.

Hier ist ein minimales Beispiel, um das Problem zu reproduzieren:

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

Ich verwende Blender 2.83.6 LTS und führe diesen Befehl aus, um das Skript auszuführen:

blender --background --python .\minimal_blender.py

Ich habe das Gefühl, etwas Einfaches zu übersehen (ich bin schließlich ein Anfänger von Blender), aber ich kann nicht feststellen, was?

Hinweis: Mir ist bewusst, dass --background etwas damit zu tun haben könnte, aber ich kann diese Option nicht deaktivieren, da dies RuntimeError: Operator bpy.ops.wm.append.poll() failed, context is incorrectin meinem anderen Skript überall eine ganze Reihe von Fehlern verursacht, von denen ich keine Ahnung habe, wie reparieren. Ich denke, diese Frage ist im Wesentlichen, wie man den Viewer-Knoten zwingt, zu aktualisieren, wenn Blender im Hintergrund ausgeführt wird.

Antworten

1 aviator Sep 25 2020 at 22:36

Gelöst - mein Problem hing tatsächlich mit Blenders fest codiertem Verhalten im Hintergrundmodus zusammen und nicht mit einem Fehler beim Rendern. Damit der Viewer-Knoten im Hintergrundmodus funktioniert, müssen Sie den Quellcode ändern und Blender wie im Link beschrieben neu kompilieren , da er aus Optimierungsgründen standardmäßig deaktiviert ist. Dann renne:

path\to\recompiled\blender --background --python my_render_script.py