24. Oktober 2024

Implementierung eines Motion-Vectors-Pass für Post-Processing

Neue Evergine-Version Motion Vectors sind eine wesentliche Komponente bei der Arbeit mit Post-Processing-Techniken wie Temporal Anti-Aliasing (TAA) und Motion Blur. In Evergine ermöglicht ein Motion-Vectors-Pass der GPU, die Bewegung von Objekten und Pixeln zwischen Frames zu verfolgen, was flüssigere visuelle Effekte ermöglicht.

Was sind Motion Vectors?

Motion Vectors speichern Informationen darüber, wie sich jedes Pixel von einem Frame zum nächsten bewegt. Dies ist entscheidend für Evergine-Post-Processing-Techniken wie TAA, bei denen der Algorithmus Samples über mehrere Frames akkumuliert, um Aliasing-Artefakte zu reduzieren, und dabei die Motion-Vector-Textur nutzt, um die vorherige Position des Pixels zu ermitteln.

Ebenso simulieren Motion-Blur-Effekte die Bewegungsunschärfe sich bewegender Objekte anhand ihrer Geschwindigkeit auf dem Bildschirm. Beide Effekte sind in hohem Maße auf präzise Motion Vectors angewiesen, um die passenden visuellen Anpassungen zu berechnen.

Überarbeiteter Render Path zur Unterstützung von Motion Vectors

In unserem Standard-Render Path verwendet Evergine ein Forward-Rendering-System. Es benötigt jedoch einige zusätzliche Passes, um nützliche Informationen für das Post-Processing zu speichern. Bisher haben wir einen ersten Render-Pass (ZPrePass) verwendet, um eine Textur mit Informationen zu Tiefe, Metalness und Roughness zu erzeugen. Die Notwendigkeit, eine Motion-Vectors-Textur zu erzeugen, hat uns veranlasst, den Render Path im Sinne von Übersichtlichkeit und Effizienz neu zu organisieren. Das folgende Diagramm erläutert die Änderungen:

ZPrePass

Die ZPrePass-Stufe hat jetzt nur noch eine Textur:

NameFormatBeschreibung
DepthD24S8Informationen zu Tiefe und Stencil. Nützlich für zahlreiche Post-Processing-Effekte.

Abbildung 1: DepthStencil-Textur

GBuferPass

Wir haben die bisherige Distortion-Stufe entfernt und einen neuen MRT-Pass (Multiple Render Target) mit mehr Framebuffern erstellt, der die bisherigen Informationen zusammen mit der neuen Motion-Vector-Textur enthält.

TexturFormatBeschreibung
RT 0R8G8B8A8_UnormSpeichert mehrere Informationen:

– R, G: Normalen, verwendet in SSAO und SSR.

– B: Roughness, verwendet in SSR

– A: Metalness, verwendet in SSR.

RT 1R16G16_FloatDie neue Motion-Vector-Textur. Sie speichert die X- und Y-Geschwindigkeit des Pixels im Bildschirmraum. Wird für das Post-Processing mit Temporal Antialiasing und Motion Blur verwendet.
RT 2R8G8B8A8_UnormEnthält die Verzerrungsinformationen für den Distortion-Post-Processing-Effekt.

 

Abbildung 2: Motion-Vectors-Textur, auf eine normale RGB-Textur begrenzt

Abbildung 3: Textur mit Normalen, Roughness und Metalness

DefaultPass

Gegenüber der Vorgängerversion unverändert ist dies der Haupt-Pass, in dem alle Objekte mit Forward-Beleuchtung und PBR in die Szene gerendert werden, wobei bei Bedarf die vorherigen Passes genutzt werden. Seine Texturen sind:

NameFormatBeschreibung
ColorR16G16B16A16_Float HDR-Textur mit der Farbe im linearen Farbraum.
DepthD24S8Textur mit der endgültigen Tiefe und dem Stencil.

Abbildung 4: Farbtextur (vor dem Post-Processing) in linearen Farben

 

Nachdem das Post-Processing angewendet und die Farbe in den Gamma-Farbraum korrigiert wurde, erhalten wir das Endergebnis.

Änderungen an der Engine

Die Einführung der Motion-Vector-Funktion in Evergine erforderte folgende Änderungen an der Engine:

  • Transform3D speichert die World-Matrix des vorherigen Frames (PreWorld ), damit die vorherige Pixelposition rekonstruiert werden kann.
  • SkinnedMeshRenderer speichert jetzt die Positionen aller Vertices des vorherigen Frames.
  • Effekte verfügen jetzt über einen neuen Metatag für den Zugriff auf die Matrizen des vorherigen Frames [PreWorld].
  • Bei Skinned Meshes wird die Vertex-Position des vorherigen Frames in der Semantik Position1 gespeichert (während Position_0 wie üblich die Position des aktuellen Frames enthält).
Antonio avila
Autor
Antonio Ávila
Plain Concepts Research