
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:
| Name | Format | Beschreibung |
| Depth | D24S8 | Informationen 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.
| Textur | Format | Beschreibung |
| RT 0 | R8G8B8A8_Unorm | Speichert mehrere Informationen: – R, G: Normalen, verwendet in SSAO und SSR. – B: Roughness, verwendet in SSR – A: Metalness, verwendet in SSR. |
| RT 1 | R16G16_Float | Die 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 2 | R8G8B8A8_Unorm | Enthä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:
| Name | Format | Beschreibung |
| Color | R16G16B16A16_Float | HDR-Textur mit der Farbe im linearen Farbraum. |
| Depth | D24S8 | Textur 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).
