Die SRP, die 2018.1 in der Beta-Version eingeführt wurde, ist eine Methode zur Konfiguration und Ausführung von Rendering in Unity, die von einem C#-Skript gesteuert wird. Bevor Sie eine benutzerdefinierte Render-Pipeline schreiben, ist es wichtig zu verstehen, was wir genau meinen, wenn wir von Render-Pipeline sprechen.

Was ist eine Render-Pipeline?

Render-Pipeline ist ein Oberbegriff für eine Reihe von Techniken, mit denen Objekte auf dem Bildschirm gebracht werden. Es umfasst auf einem sehr hohen Niveau:

Zusätzlich zu diesen High-Level-Konzepten kann jede Verantwortung weiter aufgeschlüsselt werden, je nachdem, wie sie ausgeführt werden soll. Beispielsweise können Rendering-Objekte mit Hilfe von:

Multi-pass Rendering

  • ein Durchgang pro Objekt und pro Leuchte

Single Pass

  • ein Durchgang pro Objekt

Deferred

  • Rendern Sie Oberflächeneigenschaften in einem g-Puffer, führen Sie eine Bildschirmbeleuchtung hinzu.

Wenn Sie ein benutzerdefiniertes SRP schreiben, sind dies die Art von Entscheidungen, die Sie treffen müssen. Jede Technik hat eine Reihe von Kompromissen, die Sie in Betracht ziehen sollten.

For privacy reasons YouTube needs your permission to be loaded. For more details, please see our Datenschutzerklärung.

Demoprojekt.

Alle Funktionen, die in diesem Beitrag besprochen werden, können Sie in einem Demo-Projekt auf GitHub begutachten.

Einstiegspunkt für das Rendering.

Wenn Sie SRP verwenden, müssen Sie eine Klasse definieren, die das Rendern steuert – dies ist die Render-Pipeline, die Sie erstellen werden. Der Einstiegspunkt ist ein Aufruf von „Render“, der den Renderkontext und eine Liste der zu rendernden Kameras aufnimmt.

Copy to Clipboard

Der Kontext der Render-Pipeline.

SRP rendert mit dem sogenannten „Concept of delayed execution“. Als Benutzer bauen Sie eine Liste von Befehlen auf und führen diese dann aus. Das Objekt, das Sie zum Aufbau dieser Befehle verwenden, wird als SkriptableRenderContext bezeichnet. Wenn Sie den Kontext mit Operationen befüllt haben, können Sie mit Submit aufrufen, um alle in der Warteschlange stehenden Draw-Aufrufe einzureichen.

Ein Beispiel hierfür ist das Löschen eines Renderziels mit Hilfe eines Command Buffers, der vom Renderkontext durchgeführt wird:

Copy to Clipboard

Hier finden Sie eine komplette Render-Pipeline, die einfach den Bildschirm leert.

Culling.

Culling ist der Prozess, bei der man herausfindet, was auf dem Bildschirm gerendert werden soll.

Culling umfasst in Unity:

  • Frustum Culling: Berechnen der Objekte, die zwischen der Kamera in der Nähe und der Ferne liegen.
  • Occlusion Culling: Berechnen, welche Objekte hinter anderen Objekten verborgen sind und schließen diese vom Rendering aus.

Wenn das Rendern beginnt, muss als erstes berechnet werden, was gerendert werden soll. Dabei wird die Kamera mitgenommen und das Culling erfolgt aus der Perspektive der Kamera. Die Cull Operation gibt eine Liste von Objekten und Lichtern zurück, die für das Rendern der Kamera gültig sind. Diese Objekte werden dann später in der Renderpipeline verwendet.

Culling in SRP.

In SRP führen Sie das Objekt-Rendering in der Regel aus der Perspektive einer Kamera durch. Dies ist das gleiche Kamera-Objekt, das Unity für das eingebaute Rendering verwendet. SRP stellt eine Reihe von APIs zur Verfügung, mit denen man mit dem Culling beginnen kann. Im Allgemeinen sieht der Flow wie folgt aus:

Copy to Clipboard

Die Ergebnisse, die beim Culling der Daten ausgefüllt werden, können nun für das Rendern verwendet werden.

Drawing.

Nun, da wir eine Reihe von Cullingergebnissen haben, können wir sie auf den Bildschirm übertragen.

Aber es gibt so viele Möglichkeiten, Dinge zu konfigurieren, dass eine Reihe von Entscheidungen im Vorfeld getroffen werden müssen. Viele dieser Entscheidungen werden von ihnen bestimmt werden:

  • Die Hardware, auf die Sie die Render-Pipeline zielen, wird in den folgenden Bereichen eingesetzt.
  • Das spezifische Look and Feel, das Sie erreichen möchten.
  • Die Art des Projekts, das Sie gerade durchführen.

Denken Sie zum Beispiel an ein mobiles 2D-Sidescroller-Spiel im Vergleich zu einem PC-High-End-First-Person-Game. Diese Spiele haben sehr unterschiedliche Einschränkungen, so dass die Render-Pipelines sehr unterschiedlich sind. Einige konkrete Beispiele für konkrete Entscheidungen, die getroffen werden müssen.

  • HDR vs. LDR
  • Linear vs. Gamma
  • MSAA vs. Post Process AntiAliasing
  • PBR Materialien vs. Standard-Materialien
  • Lighting vs. No Lighting
  • Lighting Techniken
  • Shadowing Techniken

Das Treffen dieser Entscheidungen beim Schreiben einer Render-Pipeline hilft ihnen dabei, viele der Einschränkungen zu bestimmen, die beim Erstellen der Render-Pipeline gesetzt werden.

Fürs Erste werden wir einen einfachen Renderer ohne Lichter demonstrieren, der einige der Objekte undurchsichtig machen kann.

Filtering: Render Buckets und Layer.

Im Allgemeinen, wenn das Rendering-Objekt eine bestimmte Klassifizierung hat, sind sie undurchsichtig, transparent, unterirdisch oder eine beliebige Anzahl anderer Kategorien. Unity verwendet ein Konzept von Queues, um darzustellen, wann ein Objekt gerendert werden soll. Diese Queues bilden Buckets, in denen Objekte platziert werden. Wenn das Rendering von SRP aus aufgerufen wird, geben Sie an, welchen Bereich der Buckets Sie verwenden möchten.

Neben Buckets können auch Standard-Unity-Layer zum Filtern verwendet werden.

Dies ermöglicht ein zusätzliches Filtering beim Zeichnen von Objekten über SRP.

Copy to Clipboard

Draw Settings: Wie Dinge gezeichnet werden sollen.

Die Verwendung von Filtern und Culling bestimmt, was gerendert werden soll, aber dann müssen wir bestimmen, wie es gerendert werden soll. SRP bietet eine Vielzahl von Optionen, um zu konfigurieren, wie ihre Objekte, die das Filtering durchlaufen, gerendert werden sollen. Die Struktur, die zur Konfiguration dieser Daten verwendet wird, ist die Struktur „DrawRenderSettings“. Diese Struktur erlaubt es, eine Reihe von Dingen zu konfigurieren:

  • Sortierung – Die Reihenfolge, in der die Objekte gerendert werden sollen, ist z.B. Back to Front und Front to Back.
  • Per Renderer Flags – Die Einstellungen, die von Unity an den Shader übergeben werden sollten, beinhalten pro Objekt Light Probes, pro Objekt Light Maps und Ähnliches.
  • Rendering Flags – Welcher Algorithmus sollte für das Batching verwendet werden, Instancing vs. Non-Instancing.
  • Shader Pass – Welcher Shader Pass soll für den aktuellen Draw-Aufruf verwendet werden.
Copy to Clipboard

Drawing.

Jetzt haben wir die drei Dinge, die wir benötigen, um einen Draw-Call auszusprechen:

  • Cull Results
  • Filtering Regeln
  • Drawing Regeln

Wir können einen Draw-Call erteilen! Wie bei allen Dingen in SRP wird ein Draw Call als Call in den Kontext gestellt. In SRP rendern Sie normalerweise keine einzelnen Meshes, sondern geben einen Aufruf aus, welcher eine große Anzahl von Meshes auf einmal rendert. Dies reduziert den Aufwand für die Skriptausführung und ermöglicht eine schneller Ausführung auf der CPU.

Um einen Draw Call auszulösen, kombinieren wir die Funktionen, die wir aufgebaut haben.

Copy to Clipboard

Dadurch werden die Objekte in das aktuell gebundene Renderziel gezeichnet. Sie können einen Command Buffer verwenden, um das Renderziel zu wechseln, wenn Sie dies wünschen.

Einen Renderer, der opake Objekte rendert, finden Sie hier.

Dieses Beispiel kann noch erweitert werden, indem transparentes Rendering hinzugefügt wird.

Wichtig dabei zu wissen ist, dass beim transpatenten Rendern die Reihenfolge der Darstellung von hinten nach vorne geändert wird.

Wir hoffen, dass dieser Beitrag ihnen dabei helfen wird, mit dem Schreiben ihrer eigenen benutzerdefinierten SRP zu beginnen. Hier können Sie die 2018.1-Beta-Version herunterladen, um sofort loszulegen.