Zeichnen mit Renderzielen in Unreal Engine


Das Renderziel ist im Wesentlichen eine Textur, in die Sie zur Laufzeit schreiben können. Aus Sicht des Motors speichern sie Informationen wie Grundfarbe, Normalen und Umgebungsokklusion.

Aus Sicht des Benutzers werden Renderziele hauptsächlich als eine Art zusätzliche Kamera verwendet. Sie können die Szenenaufnahme irgendwann einstellen und das Bild im Renderziel speichern. Anschließend können Sie das Renderziel auf dem Netz anzeigen, um beispielsweise eine Überwachungskamera zu simulieren.

Nach der Veröffentlichung der 4.13-Engine-Version hat Epic die Möglichkeit hinzugefügt, Materialien mithilfe von Blunts direkt auf das Rendering-Ziel zu zeichnen. Mit dieser Funktion können Sie komplexe Effekte wie Flüssigkeitssimulation und Schneeverformung erstellen. Klingt erstaunlich, oder? Bevor Sie jedoch zu solch komplexen Effekten übergehen, sollten Sie sich mit etwas Einfachem vertraut machen. Was könnte einfacher sein als das Zeichnen auf einem Renderziel?

In diesem Tutorial lernen Sie Folgendes:

  • Erstellen Sie Renderziele dynamisch mit Blunts
  • Renderziel auf Netz anzeigen
  • Zeichnen Sie eine Textur auf das Renderziel
  • Ändere Pinselgröße und Textur während des Spiels

Hinweis: In diesem Lernprogramm wird davon ausgegangen, dass Sie bereits mit den Grundlagen der Arbeit mit Unreal Engine vertraut sind. Wenn Sie Unreal Engine noch nicht kennen, lesen Sie unsere zehnteilige Reihe von Unreal Engine- Tutorials für Anfänger .

An die Arbeit gehen


Beginnen wir mit dem Herunterladen von Materialien für dieses Tutorial (Sie können sie hier herunterladen). Entpacken Sie sie, gehen Sie zu CanvasPainterStarter und öffnen Sie CanvasPainter.uproject . Wenn Sie auf Wiedergabe klicken, wird Folgendes angezeigt:


Das Quadrat in der Mitte (Leinwand) ist das, worauf wir zeichnen werden. Die UI-Elemente auf der linken Seite sind die Textur, die wir zeichnen werden, und ihre Größe.

Schauen wir uns zunächst die Methode zum Zeichnen an.

Zeichenmethode


Das erste, was wir brauchen, ist ein Renderziel, das als Zeichenfläche verwendet wird. Um zu bestimmen, wo auf dem Renderziel gezeichnet werden soll, verfolgen wir die gerade Linie, die aus der Kamera nach vorne kommt. Wenn die Linie die Leinwand schneidet, können wir den Schnittpunkt im UV-Raum erhalten.

Wenn die Leinwand beispielsweise eine perfekte Bindung der UV-Koordinaten aufweist, gibt der Schnittpunkt in der Mitte den Wert (0,5, 0,5) zurück . Wenn die Linie die Leinwand in der unteren rechten Ecke kreuzt, erhalten wir den Wert (1, 1) . Anschließend können Sie mithilfe einfacher Berechnungen den Ort der Zeichnung berechnen.


Aber warum die Koordinaten im UV-Raum bekommen? Warum nicht die Koordinaten des realen Weltraums verwenden? Wenn wir den Raum der Welt nutzen, müssen wir zuerst den Schnittpunkt relativ zur Ebene berechnen. Sie müssen auch die Drehung und den Maßstab der Ebene berücksichtigen.

Bei Verwendung des UV-Raums sind alle diese Berechnungen nicht erforderlich. In einer Ebene mit perfekter Bindung der UV-Koordinaten kehrt der Schnittpunkt mit der Mitte immer zurück (0,5, 0,5) , unabhängig von der Position und Drehung der Ebene.

Hinweis: Die in diesem Lernprogramm beschriebene Methode funktioniert im Allgemeinen nur mit Ebenen oder Oberflächen, die Ebenen ähnlich sind. Andere Arten von Geometrie erfordern eine komplexere Methode, die ich in einem anderen Tutorial behandeln werde.

Zuerst erstellen wir Material, das das Renderziel rendert.

Erstellen Sie Leinwandmaterial


Gehen Sie zum Ordner Materialien und öffnen Sie M_Canvas .

In diesem Tutorial erstellen wir Renderziele dynamisch mithilfe von Blunts. Dies bedeutet, dass wir die Textur als Parameter einrichten müssen, damit wir sie an das Rendering-Ziel übergeben können. Erstellen Sie dazu ein TextureSampleParameter2D und nennen Sie es RenderTarget . Schließen Sie es dann an BaseColor an .


Machen Sie sich vorerst keine Gedanken über die Auswahl einer Textur - wir werden dies später in Blaupausen tun. Klicken Sie auf Übernehmen und schließen Sie M_Canvas .

Der nächste Schritt besteht darin, ein Renderziel zu erstellen, wonach wir es als Canvas-Material verwenden.

Erstellen eines Renderziels


Es gibt zwei Möglichkeiten, ein Renderziel zu erstellen. Erstens: Erstellen im Editor durch Klicken auf Add New \ Materials & Textures \ Render Target . Mit dieser Methode können Sie dasselbe Renderziel bequem auf mehrere Akteure verweisen. Wenn wir jedoch mehrere Leinwände benötigen, müssen wir für jede Zeichenfläche manuell ein Renderziel erstellen.

Daher ist es besser, Renderziele mit Blunts zu erstellen. Der Vorteil dieses Ansatzes besteht darin, dass wir Renderziele nur bei Bedarf erstellen und sie die Größe der Projektdateien nicht erhöhen.

Zuerst müssen wir ein Renderziel erstellen und es als Variable für die zukünftige Verwendung speichern. Gehen Sie zum Ordner Blueprints und öffnen Sie BP_Canvas . Suchen Sie das Ereignis BeginPlay und fügen Sie die ausgewählten Knoten hinzu.


Stellen Sie Breite und Höhe auf 1024 ein . Daher ändern wir die Auflösung des Renderziels auf 1024 × 1024 . Je höher der Wert, desto höher die Bildqualität, aber auch die Kosten für den Videospeicher.


Als nächstes kommt der 2D- Knoten Clear Render Target . Mit diesem Knoten können Sie die Farbe des Renderziels festlegen. Stellen Sie Clear Color auf (0,07, 0,13, 0,06) . In diesem Fall wird das gesamte Renderziel mit grünlicher Farbe gefüllt.


Jetzt müssen wir das Renderziel auf dem Canvas-Netz anzeigen.

Zielanzeige rendern


Zu diesem Zeitpunkt verwendet das Canvas-Netz das Standardmaterial. Um das Renderziel anzuzeigen, müssen Sie eine dynamische Instanz von M_Canvas erstellen und das Renderziel an dieses übergeben. Anschließend müssen Sie eine dynamische Instanz des Materials auf das Canvas-Netz anwenden. Dazu fügen wir die ausgewählten Knoten hinzu:


Fahren wir zunächst mit dem Knoten Dynamische Materialinstanz erstellen fort und setzen den übergeordneten Wert auf M_Canvas . Also werden wir eine dynamische Instanz von M_Canvas erstellen .


Wechseln Sie als Nächstes zum Knoten Set Texture Parameter Value und setzen Sie den Parameternamen auf RenderTarget . Daher übergeben wir das Renderziel an den zuvor erstellten Texturparameter.


Jetzt wird das Renderziel auf dem Canvas-Netz angezeigt. Klicken Sie auf Kompilieren und kehren Sie zum Haupteditor zurück. Klicken Sie auf Wiedergabe, um zu sehen, wie sich die Farbe der Leinwand ändert.


Nachdem wir die Leinwand haben, müssen wir Material erstellen, das als Pinsel verwendet werden kann.

Pinselmaterial erstellen


Gehen Sie zum Ordner Materialien . Erstellen Sie das Material M_Brush und öffnen Sie es. Stellen Sie zuerst den Mischmodus auf Durchscheinend . Dadurch können wir Texturen mit Transparenz verwenden.


Wie bei Leinwandmaterial setzen wir die Textur für den Pinsel in Blunts. Erstellen Sie ein TextureSampleParameter2D und nennen Sie es BrushTexture . Schließen Sie es wie folgt an:


Klicken Sie auf Übernehmen und schließen Sie M_Brush .

Als Nächstes erstellen Sie eine dynamische Instanz des Pinselmaterials, damit Sie die Textur des Pinsels ändern können. Öffnen Sie BP_Canvas und fügen Sie die ausgewählten Knoten hinzu.


Wechseln Sie als Nächstes zum Knoten Dynamische Materialinstanz erstellen und setzen Sie das übergeordnete Element auf M_Canvas .


Wir haben das Pinselmaterial erstellt und benötigen nun eine Funktion zum Malen mit dem Pinsel auf dem Renderziel.

Pinselmalerei auf Renderziel


Erstellen Sie eine neue Funktion und nennen Sie sie DrawBrush . Zuerst benötigen wir die Parameter: verwendete Textur, Pinselgröße und Ort zum Zeichnen. Erstellen Sie die folgende Eingabe:

  • BrushTexture: Wählen Sie den Typ Texture 2D
  • BrushSize: Float- Typ auswählen
  • DrawLocation: Wählen Sie den Typ Vector 2D


Bevor wir einen Pinsel zeichnen, müssen wir seine Textur einstellen. Erstellen Sie dazu die unten gezeigte Schaltung. Stellen Sie sicher, dass BrushTexture als Parametername ausgewählt ist .


Jetzt müssen wir das Rendern im Renderziel durchführen. Erstellen Sie dazu die ausgewählten Knoten:


Wenn Sie mit dem Zeichnen von Canvas zum Rendern von Zielen beginnen, wird die Engine darüber informiert, dass das Rendern für ein bestimmtes Renderziel gestartet werden soll. Mit Material zeichnen können Sie Material an einer bestimmten Stelle mit der ausgewählten Größe und Drehung zeichnen.

Die Berechnung der Renderposition erfolgt in zwei Schritten. Zuerst müssen wir DrawLocation so skalieren , dass es in die Renderzielauflösung passt. Multiplizieren Sie dazu DrawLocation mit Size .


Standardmäßig rendert die Engine Materialien anhand der oberen linken Ecke als Ausgangspunkt. Daher wird die Pinselstruktur nicht auf uns zentriert, wo wir rendern möchten. Um dies zu beheben, müssen wir BrushSize durch 2 teilen und dann das Ergebnis vom vorherigen Schritt subtrahieren.


Dann verbinden wir alles wie folgt:


Schließlich müssen wir der Engine mitteilen, dass das Rendern im Renderziel gestoppt werden soll. Fügen Sie den End Draw Canvas zum Render Target- Knoten hinzu und verbinden Sie ihn wie folgt:


Jedes Mal, wenn DrawBrush ausgeführt wird , wird zuerst die übertragene Textur als Textur für BrushMaterial festgelegt . Anschließend rendert sie das BrushMaterial im RenderTarget unter Verwendung der übergebenen Position und Größe.

Und damit ist die Rendering-Funktion fertig. Klicken Sie auf Kompilieren und schließen Sie BP_Canvas . Der nächste Schritt besteht darin, die Linie von der Kamera zu verfolgen und an der Stelle der Leinwand zu zeichnen, an der der Schnittpunkt aufgetreten ist.

Kamera direkte Spur


Bevor wir auf die Leinwand zeichnen, müssen wir die Pinselstruktur und -größe angeben. Gehen Sie zum Ordner Blueprints und öffnen Sie BP_Player . Setzen Sie dann die Variable BrushTexture auf T_Brush_01 und die Variable BrushSize auf 500 . Also weisen wir ein Pinselbild eines Affen mit einer Größe von 500 × 500 Pixel zu.


Als nächstes müssen Sie die Linie verfolgen. Suchen Sie InputAxis Paint und erstellen Sie das folgende Diagramm:


Wir werden also die Linie verfolgen, die direkt von der Kamera gerichtet ist, während der Player die dem Malen zugewiesene Taste hält (in unserem Fall ist dies die linke Maustaste ).

Jetzt müssen wir überprüfen, ob die gerade Leinwand gekreuzt ist. Ausgewählte Knoten hinzufügen:


Wenn sich nun die Linie und die Leinwand schneiden , wird die DrawBrush- Funktion unter Verwendung der Pinselvariablen und der an sie übergebenen UV-Koordinaten ausgeführt.

Damit der UV- Knoten " Kollision suchen" funktioniert, müssen zwei Parameter geändert werden. Wechseln Sie zunächst zum LineTraceByChannel- Knoten und aktivieren Sie Trace Complex .


Gehen Sie zweitens zu Bearbeiten \ Projekteinstellungen und dann zu Engine \ Physics . Aktivieren Sie Support UV From Hit Results und starten Sie das Projekt neu.


Klicken Sie nach dem Neustart auf Wiedergabe , um auf die Leinwand zu zeichnen, und klicken Sie mit der linken Maustaste .


Sie können sogar mehrere Leinwände erstellen und jeweils einzeln darauf zeichnen. Dies ist möglich, da jede Zeichenfläche dynamisch ein eigenes Renderziel erstellt.


Im nächsten Abschnitt implementieren wir die Funktion zum Ändern der Pinselgröße eines Spielers.

Pinselgröße ändern


Öffnen Sie BP_Player und suchen Sie den InputAxis ChangeBrushSize- Knoten. Diese Achsenbindung ist für die Verwendung des Mausrads konfiguriert. Um die Pinselgröße zu ändern, reicht es aus, den BrushSize- Wert abhängig vom Achsenwert zu ändern. Erstellen Sie dazu das folgende Schema:


Es wird eine Addition oder Subtraktion von BrushSize durchgeführt, wenn der Player das Mausrad verwendet. Die erste Multiplikation bestimmt die Additions- oder Subtraktionsrate. Als Sicherheitsmaßnahme wurde eine Klemme (Schwimmer) hinzugefügt. Es stellt sicher, dass die Pinselgröße nicht kleiner als 0 oder größer als 1000 wird .

Klicken Sie auf Kompilieren und kehren Sie zum Haupteditor zurück. Drehen Sie das Mausrad, um die Größe des Pinsels beim Zeichnen zu ändern.


Im letzten Abschnitt erstellen wir eine Funktion, mit der der Spieler die Textur des Pinsels ändern kann.

Pinselstruktur ändern


Zuerst benötigen wir ein Array, um die Texturen zu speichern, die der Player verwenden kann. Öffnen Sie BP_Player und erstellen Sie eine Array- Variable. Wählen Sie den 2D- Texturtyp aus und nennen Sie ihn Texturen .


Erstellen Sie dann drei Elemente in Texturen . Weisen Sie ihnen folgende Werte zu:

  • T_Brush_01
  • T_Brush_02
  • T_Brush_03


Dies sind die Texturen, die der Spieler zeichnen kann. Um neue Texturen hinzuzufügen, fügen Sie sie einfach diesem Array hinzu.

Als nächstes benötigen wir eine Variable, um den aktuellen Index des Arrays zu speichern. Erstellen Sie eine Ganzzahlvariable und nennen Sie sie CurrentTextureIndex .


Als nächstes brauchen wir eine Möglichkeit, alle Texturen in einer Schleife zu durchlaufen. Für dieses Tutorial habe ich eine Aktionszuordnung namens NextTexture eingerichtet und an die rechte Maustaste gebunden. Wenn der Spieler diese Taste drückt, sollte der Übergang zur nächsten Textur durchgeführt werden. Suchen Sie dazu den InputAction NextTexture- Knoten und erstellen Sie das folgende Diagramm:


Dieses Schema erhöht CurrentTextureIndex bei jedem Rechtsklick . Wenn der Index das Ende des Arrays erreicht, wird er erneut auf 0 zurückgesetzt . Schließlich legt BrushTexture die entsprechende Textur fest.

Klicken Sie auf Kompilieren und schließen Sie BP_Player . Klicken Sie auf Wiedergabe und klicken Sie mit der rechten Maustaste , um zwischen den Texturen zu wechseln.


Wohin als nächstes?


Das fertige Projekt kann hier heruntergeladen werden .

Render Target ist ein äußerst leistungsfähiges Tool. In diesem Tutorial haben wir nur die Grundlagen behandelt. Wenn Sie wissen möchten, wozu Renderziele in der Lage sind, lesen Sie Content-Driven Multipass Rendering in UE4 . Dieses Video enthält Beispiele für Zeichnungsflusskarten, Volumenzeichnungen, Flüssigkeitssimulationen und mehr.

In unserem Tutorial-Video zum Zeichnen von Blaupausen zum Rendern von Zielen erfahren Sie auch, wie Sie eine Höhenkarte mit Renderziel erstellen.

Source: https://habr.com/ru/post/de420031/


All Articles