Loop

Loop

Mit der Komponente Loop kannst du einen Teilbaum von Komponenten mehrfach rendern und die Ergebnisse all dieser Iterationen zu einem einzigen Ausgabebild kombinieren.

Im Wesentlichen ermöglicht Loop, dass ein Teilbaum von Komponenten mehrfach in sich selbst "hineingesteckt" werden kann, wobei seine eigene Ausgabe als Eingabe dient. Das heißt, Loop bietet die Benutzerschnittstelle und die interne Logik (vor allem die Abbruchbedingung) für zirkuläre Verbindungen. Andernfalls werden solche Verbindungen von Filter Forge nicht zugelassen.

Die Komponente Loop kann ohne ihre Slave-Komponenten nicht funktionieren. Ihre Ausgabe ändert sich in Abhängigkeit von der aktuellen Iteration des Loops - das bedeutet, dass du sie verwenden kannst, um eine beliebige Anzahl von Parametern im Teilbaum des Loops von Iteration zu Iteration zu verändern.

Weitere Informationen zu den Slave-Komponenten von Loop findest du unter "Beispiele" und "Slave-Komponenten verwenden". Allgemeine Informationen über Slave-Komponenten findest du unter: Slave-Komponenten.

Loop ist eine Abbildungs-Komponente, die in der Kategorie Erweitert in der Komponentenleiste zu finden ist. Diese Komponente kann HDR-Farben ausgeben.

Akkumulator: Abbildungs-Eingabe (HDR), Erforderlich

Definiert das Ergebnis einer Loop-Iteration, das dann an die Slave-Komponente Akkumuliert zurückgegeben wird, um in der nächsten Loop-Iteration rekursiv verarbeitet zu werden. Akkumulator ist ein erforderlicher Eingang – damit der Filter funktioniert, muss dieser Eingang angeschlossen sein. Der Eingang akzeptiert HDR-Farben.

Iterationen: Numerische Eingabe

Legt die Anzahl der Iterationen bzw. Zyklen des Loops fest. Das heißt, wie oft der Teilbaum Loop die kombinierte Ausgabe aller vorherigen Iterationen verarbeitet.

Slave-Komponenten

Mit diesen Schaltflächen werden Slave-Komponenten erstellt, die mit der aktuell ausgewählten Loop-Komponente verknüpft sind. Du kannst mehrere Kopien jeder Slave-Komponente haben, mit Ausnahme der Komponente Akkumuliert.

Akkumuliert hinzufügen:
Fügt eine erforderliche Akkumuliert-Slave-Komponente hinzu, die das kombinierte Ergebnis aller vorherigen Iterationen des Loops ausgibt, das dann mit dem Ergebnis der aktuellen Iteration kombiniert und in den Akkumulator-Eingang des Loops eingespeist wird. Diese Slave-Komponente ist für das Funktionieren jedes Loops erforderlich und kann nicht mehrfach kopiert werden.

Position hinzufügen:
Fügt eine optionale Positions-Slave-Komponente hinzu, die den "Fertigstellungsgrad" des Loops als normalisierte, in Farbe umgewandelte Iterationszahl ausgibt.

Iteration hinzufügen:
Fügt eine optionale Iterations-Slave-Komponente hinzu, die die Nummer der aktuellen Iteration des Loops als HDR-Farbe mit RGB-Werten ausgibt, die der Nummer der aktuellen Iteration entsprechen (1, 2, 3...).

Zufallsgenerator hinzufügen:
Fügt eine optionale Zufallsgenerator-Slave-Komponente hinzu, die einen normalisierten Zufallswert (in Farbe umgewandelt) ausgibt, der für jede Loop-Iteration eindeutig ist. Mehrere Zufallsgeneratoren können unterschiedliche Variations-einstellungen (d.h. Zufallssamen) haben.

Beispiele

Das folgende Beispiel demonstriert einen einfachen Loop:

Multistar.ffxml

Der obige Loop funktioniert folgendermaßen:

  1. Die Anzahl der Iterationen, im obigen Beispiel 5, wird in den Eigenschaften der Komponente Loop festgelegt.
  2. Die Slave-Komponente Akkumuliert liefert das kombinierte Ergebnis aller vorherigen Iterationen an den Loop-Teilbaum.
  3. Der Loop-Teilbaum, der in diesem Beispiel aus einer einzigen Freien Polygon-Komponente besteht, modifiziert das kumulierte Ergebnis aller vorherigen Iterationen, um die aktuelle Iteration zu erzeugen. Eine Positions-Slave-Komponente wird verwendet, um den Drehwinkel des Sterns von Iteration zu Iteration zu verändern.
  4. Nach der Bildung des Loop-Teilbaums wird die Ausgabe der aktuellen Iteration an Loop gesendet;
  5. Und bei der nächsten Iteration wird sie am Ausgang von Akkumuliert erscheinen. Wiederhole den Vorgang ab Schritt 2 vier weitere Male.

Du kannst mehrere Slave-Komponenten mit einem einzigen Loop verknüpfen (mit Ausnahme von Akkumuliert, die nicht mehrere Kopien haben kann). In diesem Beispiel werden mehrere Zufallsgeneratoren verwendet, jeder mit einem eigenen Farbbereich und einer eigenen Variation (d. h. einem Zufallssamen), um mehrere Eingänge des Loop-Teilbaums zu randomisieren:

Multiple Randomizers.ffxml

Slave-Komponenten verwenden

Die Komponente Loop kann ohne ihre Slave-Komponenten nicht funktionieren. Das Wichtigste an den Slave-Komponenten ist, dass sich ihre Ausgabe in Abhängigkeit von der aktuellen Loop-Iteration ändert. Das bedeutet, dass du sie verwenden kannst, um eine beliebige Anzahl von Parametern im iterierten Teilbaum von Iteration zu Iteration zu verändern.

Die Slave-Komponenten von Loop funktionieren nur dann richtig, wenn die folgenden Bedingungen erfüllt sind:

  1. Slave-Komponenten müssen mit dem Teilbaum des Akkumulator-Eingangs über einen Teilbaum von Komponenten verbunden sein, nicht direkt, sonst haben sie keine Wirkung.
  2. Zwischen dem Slave und dem Akkumulator-Eingang dürfen sich keine Bitmap-basierten Komponenten befinden. Bitmap-basierte Komponenten (wie z. B. Unschärfe oder Bewegungsunschärfe) zerstören die vom Master an den Slave gesendeten Elementdaten und können daher nicht in Slave-zu-Master-Verbindungen verwendet werden.

Verschachtelte Loops

Loops können verschachtelt werden. Im folgenden Beispiel erzeugt ein innerer Loop eine Reihe von 5 Kreisen, die dann von dem äußeren Loop fünfmal dupliziert wird. Beachte, dass Slave-Komponenten des äußeren Loops, Komponenten im Teilbaum des inneren Loops beeinflussen können:

Nested Loops.ffxml

Optimierung der Geschwindigkeit von Loops

Technisch gesehen werden Loops durch rekursive Aufrufe der Sampling Funktion des Teilbaums implementiert, der mit dem Akkumulator-Eingang der Loop-Komponente verbunden ist. Das bedeutet, dass es möglich ist, eine exponentiell wachsende Rekursion zu erhalten, wenn der Loop-Teilbaum mehr als ein Sample von der Akkumulierten-Slave-Komponente anfordert. Wenn du eine exponentiell wachsende Rekursion mit einer relativ hohen Anzahl von Iterationen in deinen Filter hast (die so niedrig wie 7 oder 8 sein kann), können die Render-Zeiten so groß werden, dass du möglicherweise nie ein gerendertes Ergebnis siehst.

Hier ein Beispiel für das manuelle Abwickeln eines Loops mit einer exponentiellen Rekursion.

Der originale Filter:

Die manuell aufgerollte Version:

Das sind 3 * (1 + 2 + 4 + 8 + 16 + 32 + 64) = 381 Komponenten, die ausgewertet werden müssen, um das Ergebnis zu berechnen. Erhöht man die Iterationszahl von 7 auf 8, erhält man 3 * (1 + 2 + 4 + 8 + 16 + 32 + 64 + 128) = 765 Komponenten: Die Anzahl der Komponenten verdoppelt sich im Grunde mit jeder zusätzlichen Iteration. Wenn du den Teilbaum des Loops so änderst, dass er drei Samples an Akkumuliert sendet, anstatt wie oben gezeigt zwei, erhältst du 3 * (1 + 3 + 9 + 27 + 81 + 243 + 729 + 2187) = 9840 auszuwertende Komponenten.

Hier sind drei Faustregeln, um exponentielle Rekursionen in Schach zu halten:

  1. Halte die Anzahl der Loop-Iterationen so gering wie möglich.
  2. Minimiere die Anzahl der Sampling-Aufrufe an Akkumuliert. Das heißt, alle Komponenten im Loop-Teilbaum zwischen der Slave-Komponente Akkumuliert und dem Akkumulator-Eingang des Loops sollten so wenige ausgehende Verbindungen wie möglich haben:

  3. Um exponentielle Rekursionen gänzlich zu vermeiden, begrenze die Anzahl der Samples in Akkumuliert auf einen pro Loop, wie unten gezeigt. Solche Rekursionen werden in saubere lineare Ketten von Komponenten aufgerollt, im Gegensatz zu den sich ständig verzweigenden Bäumen exponentieller Rekursionen:

Beachte auch, dass die Begrenzung der Anzahl der Samples auf Akkumuliert dir nicht dabei hilft, mit Komponenten umzugehen, die ihre Eingänge mehrfach an verschiedenen Koordinaten sampeln, wie z. B. Kanten-Detektor und Ableitung. Eine einzige solche Komponente in einen Loop zwischen Akkumuliert und Akkumulator garantiert eine exponentielle Rekursion.

Beschränkungen von Loops

Urheberrecht © 2006-2022 Filter Forge, Inc. Alle Rechte vorbehalten.