Tipp: Noise Reduction Nodes mit Python verknüpfen

Tipp: Noise Reduction Nodes mit Python verknüpfen

b°wide hat der Community einen Node-Pack zur Verfügung gestellt, der neben vielen anderen Verwendungszwecken zur Reduktion von Cycles-Rauschen im Compositor benutzt werden kann. Herunterladen könnt ihr ihn hier. Es bedarf vieler Klicks diese Node Group zu benutzen, zunächst muss man alle Channels aktivieren und dann alle In- und Outputs verbinden, hier gibt es eine one-click-solution.

In diesem Artikel möchte ich mich auf die höchsteffektiven Node Groups konzentrieren, die mit Hilfe des Bilateral Blurs Rauschen aus Renderings mit wenig Qualitätsverlust stark reduzieren. Ich gehe allerdings davon aus, dass ein paar grundlegende Vorgehensweisen in Python schon bekannt sind, falls das nicht der Fall sein sollte, schaut euch bitte ein paar der ARewO Entwicklungstutorials an, bei denen ich auf Level 0 ansetze.
Hier ist das komplette Script, danach folgt die Erklärung:

  1.  

Setup:
Zunächst braucht ihr die Blenddatei, in der diese Node Groups gespeichert sind. Ladet sie mit dem Link oben herunter und speichert sie auf der Festplatte. Dann öffnet ihr die Datei in der Rauschen reduziert werden soll und geht auf File -> Append (SHIFT + F1). Navigiert im Menü zur b°wide Datei, klickt sie an und geht in das Verzeichnis NodeTree. Dort sind alle Node Groups gespeichert und ihr könnt die PassCombineDenoiser  mit einem Doppelklick auswählen. Geht danach in das Compositor Layout oder öffnet den Node Editor in einem Fenster. In den Compositing Nodes stellt ihr Use Nodes an (1). Dann SHIFT + A -> Group -> PassCombineDenoiser.

Das erstellt eine Node Group mit einer Menge Inputs. Wir haben aber nur 3 Outputs in der Render Layer  Node, also müssen wir das ändern. Im Render Layer Tab des Properties Window geht zu Passes und erweitert diese Option (2).
Bevor wir jetzt alle nötigen Passes aktivieren, schauen wir uns an, was genau passiert, wenn wir einen dieser Passes anklicken. Dazu müssen wir mit der Maus über den Rand direkt unter der Info Leiste gehen und diese herunterziehen (3). Neben der Python Console ist diese Vorgehensweise der beste Freund des Blender Python-Anfängers. Wenn wir jetzt also beispielsweise den Haken beim AO Pass setzen, kann man dort lesen:

  1.  

Jetzt müssen wir noch die restlichen notwendigen Passes anwählen. Keine Sorge, das müssen wir nur einmal machen, bei jedem weiteren Importieren wird das Skript das für uns übernehmen. In dem Python Information-Fenster könnt ihr mit B alles auswählen, was wir brauchen (alles was use_pass_ enthält). Mit der Maus immer noch über dem blau markierten Text STRG + C drücken und einen Text Editor öffnen oder zum Window Preset Scripting wechseln. Dort auf New (4) klicken, damit wir ein Skript beginnen können. Als Erstes schreiben wir: 

  1.  

Danach fügen wir den Code ein, den wir eben kopiert haben (STRG + V). Jetzt macht unser Skript dasselbe wie das, was wir eben per Hand getan haben, schon eine große Hilfe, aber da geht noch mehr. Zuerst erstellen wir ein paar Variablen, die es anderen oder uns später erleichtern nachzuvollziehen, was wir getan haben, also die Lesbarkeit verbessern:

  1.  

Man kann sich den node_tree als Verzeichnis vorstellen, die Dateien, die wir daraus verwenden, sind die Variablen: render, welche die Node im Nodetree enthält, die  'Render Layers' heißt und reduce_noise. Die nächsten Zeilen sind etwas komplizierter. Man könnte auch eine For-Schleife verwenden, um durch die Attribute der In- und Outputs zu gehen, aber diese Vorgehensweise ist die bei Python übliche.

  1.  

Erklärung: Wenn wir alle Namen der Outputs in einer Liste speichern möchten, geht das nicht mit render.outputs.names weil outputs eine Liste ist und nur die einzelnen Objekte der Liste einen Namen haben. Wir benutzen [] um zu zeigen, dass das Ergebnis eine Liste sein wird. Das n ist eine temporäre Variable, die alle Outputs einen nach dem anderen annimmt, denn jetzt können wir mit n.name sagen, dass wir den Namen des Outputs wollen. For also für alle render.outputs. Das gibt uns ein Array von allen Namen, das Outputs der oben deklarierten Variable render enthält. Die nächste Zeile macht dasselbe, mit der kleinen Einschränkung: wir wollen nur die Inputs in der Liste, die nicht versteckt sind, also deren Eigenschaft n.hide nicht wahr ist. Das ist nur eine Vorsichtsmaßnahme, falls es automatisch generierte oder eben versteckte und damit nicht benutzte Inputs geben sollte.

Jetzt möchten wir mit den Elementen in diesen Listen auch etwas anstellen. Um Python zu sagen, dass wir eine Liste abarbeiten wollen, und zwar jedes einzeln, schreibt man:

  1.  

Die Variable socket wird in jedem Zyklus einen anderen Wert annehmen, nämlich den Namen, der gerade betrachtet wird. Wir müssen alle Zeilen einrücken, die zur Schleife gehören, so zeigt man Python, wann die Schleife vorbei ist. Wahrscheinlich habt ihr schon gesehen, dass die meisten Inputs den gleichen Namen wie die Outputs haben, mit Außnahme der letzten 3, dort steht statt 'Subsuface' 'SSS'. Das verhindert zwar, dass wir die Sockets einfach mit F verbinden können und verlangt ein paar Zeilen mehr in unserem Skript, aber es hat mich trotzdem gefreut, weil es dadurch noch ein wenig mehr Sinn macht, diese Schritte tatsächlich zu skripten und nicht jedesmal per Hand macht. Außerdem können wir noch ein wenig mehr Code betrachten.

  1.  

Eines der großartigen Dinge an Python ist: Selbst wenn man keine Ahnung von Code hat, kann man doch einigermaßen erraten, was gerade passiert. Wenn also der Socket (wir erinnern uns, das ist ein Name, also String) mit 'SSS' anfängt, soll das 'SSS' durch 'Subsurface' ersetzt werden. Dann erstellen wir eine weitere Variable, die ebenfalls den ersetzten String enthält. Die Variable socket selbst zu ersetzen kann problematisch sein, da sie von der Schleife zugewiesen wird, also lieber auf Nummer sicher gehen. 

  1.  

Jetzt haben also alle zusammengehörigen In- und Outputs denselben Namen und wir können sie nach Namen verbinden. Es ist wichtig zu beachten, dass die Verbindung (link) nicht Teil der In- und Outputs ist, was auf den ersten Blick vielleicht logisch erscheinen mag, sondern Teil des Nodetrees selbst. Deshalb nt.links.new. nt war ja der gesamte Nodetree der Szene s.o.

Wir benutzen Cookies

Wir nutzen Cookies auf unserer Website. Einige von ihnen sind essenziell für den Betrieb der Seite, während andere uns helfen, diese Website und die Nutzererfahrung zu verbessern (Tracking Cookies). Sie können selbst entscheiden, ob Sie die Cookies zulassen möchten. Bitte beachten Sie, dass bei einer Ablehnung womöglich nicht mehr alle Funktionalitäten der Seite zur Verfügung stehen.