XR_EXT_frame_synthesis

Name String

XR_EXT_frame_synthesis

Erweiterungstyp

Instanzerweiterung

Registrierte Durchwahl

212

Revision

1

Ratification Status

Nicht ratifiziert

Erweiterungs- und Versionsabhängigkeiten

OpenXR 1.0

Mitwirkende

Jian Zhang, Meta Platforms
Neel Bedekar, Meta Platforms
Xiang Wei, Meta Platforms
Guodong Rong, Meta Platforms
Trevor Dasch, Meta Platforms
Rémi Arnaud, Varjo
Paulo Gomes, Samsung Electronics
Bryce Hutchings, Microsoft
Rylie Pavlik, Collabora
Shuai Liu, ByteDance

Übersicht

Diese Erweiterung bietet Unterstützung für die Aktivierung der Frame-Synthese in Anwendungen basierend auf zusätzlichen von der Anwendung bereitgestellten Daten. Von der Anwendung generierte Bewegungsvektor- und Tiefenbilder können von der Laufzeitumgebung verwendet werden, um eine hochwertige Frame-Extrapolation und ‑Reprojektion durchzuführen und einen neuen Frame zu synthetisieren. So wird auch dann eine flüssige Darstellung ermöglicht, wenn die Anwendung unter dem FPS-Zielwert ausgeführt wird.

Diese Erweiterung ist unabhängig von XR_KHR_composition_layer_depth und beide können gleichzeitig für unterschiedliche Zwecke aktiviert und verwendet werden. XrFrameSynthesisInfoEXT :: depthSubImage kann Tiefendaten verwenden, die für die Frame-Synthese vorgesehen sind, und die Auflösung kann niedriger sein als XrCompositionLayerDepthInfoKHR :: subImage . Die empfohlene Auflösung von depthSubImage findest du unter XrFrameSynthesisConfigViewEXT.

Bewegungsvektor- und Tiefenbilder einreichen

Die Struktur XrFrameSynthesisInfoEXT ist so definiert:

typedef struct XrFrameSynthesisInfoEXT {
    XrStructureType                 type;
    const void*                     next;
    XrFrameSynthesisInfoFlagsEXT    layerFlags;
    XrSwapchainSubImage             motionVectorSubImage;
    XrVector4f                      motionVectorScale;
    XrVector4f                      motionVectorOffset;
    XrPosef                         appSpaceDeltaPose;
    XrSwapchainSubImage             depthSubImage;
    float                           minDepth;
    float                           maxDepth;
    float                           nearZ;
    float                           farZ;
} XrFrameSynthesisInfoEXT;

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • layerFlags ist eine Bitmaske von XrFrameSynthesisInfoFlagsEXT .
  • motionVectorSubImage gibt das Bewegungsvektor-Image XrSwapchainSubImage an, das für die Frame-Synthese verwendet werden soll.
  • motionVectorScale ist ein XrVector4f, der die Interpretation des Bewegungsvektors in motionVectorSubImage skaliert.
  • motionVectorOffset ist ein XrVector4f, der die Interpretation des Bewegungsvektors in motionVectorSubImage verschiebt.
  • appSpaceDeltaPose ist die inkrementelle, von der Anwendung angewendete Transformation, die sich seit dem vorherigen Frame auf die Ansicht auswirkt. Bei künstlicher Fortbewegung (geskriptete Bewegung, Teleportation usw.) transformiert die Anwendung die gesamte XrCompositionLayerProjection :: space von einer Pose im Anwendungsbereich zu einer anderen Pose zwischen Frames. Dadurch wird die Ansicht stärker beeinflusst als durch die getrackte Bewegung zwischen Frames. Die appSpaceDeltaPose muss „identity“ sein, wenn in der Anwendung keine XrCompositionLayerProjection :: space-Transformation vorhanden ist. Die XrPosef :: position in appSpaceDeltaPose muss relativ zur aktuellen Anwendung XrCompositionLayerProjection :: space sein.
  • depthSubImage gibt das Tiefenbild XrSwapchainSubImage an, das für die Frame-Synthese verwendet werden soll.
  • minDepth und maxDepth sind der Bereich der Tiefenwerte in der depthSubImage und müssen im Bereich [0,0, 1,0] liegen. Dies ähnelt den Mindest- und Höchstwerten von glDepthRange in OpenGL, wobei hier die Bedingung gilt, dass maxDepth ≥ minDepth sein muss .
  • nearZ ist die positive Entfernung in Metern des minDepth-Werts in der Tiefen-Swapchain. Anwendungen können einen nearZ-Wert verwenden, der größer als farZ ist, um anzugeben, dass die Tiefenwerte umgekehrt sind. nearZ kann unendlich sein.
  • farZ ist die positive Entfernung in Metern des maxDepth-Werts in der Tiefen-Swapchain. farZ kann unendlich sein. Die Laufzeit muss den Fehler XR_ERROR_VALIDATION_FAILURE zurückgeben, wenn nearZ == farZ.

Wenn du Bewegungsvektor- und Tiefenbilder zusammen mit Projektionsebenen einreichst, füge der XrCompositionLayerProjectionView :: next-Kette für jede XrCompositionLayerProjectionView-Struktur in der angegebenen Ebene eine XrFrameSynthesisInfoEXT-Struktur hinzu.

Die Laufzeit muss die Bewegungsvektordaten in den RGB-Kanälen des motionVectorSubImage interpretieren, die durch motionVectorScale und motionVectorOffset so geändert wurden: motionVector = motionVectorSubImage rgb * motionVectorScale xyz + motionVectorOffset xyz . Die Komponenten motionVectorSubImage a , motionVectorScale w und motionVectorOffset w werden ignoriert.

Der Bewegungsvektor stellt die Bewegung eines Pixels seit der XrFrameEndInfo ::displayTime des vorherigen Frames bis zur XrFrameEndInfo ::displayTime des aktuellen Frames dar. Die Laufzeit kann diese Informationen verwenden, um den gerenderten Frame in einen zukünftigen Frame zu extrapolieren.

Der Bewegungsvektor muss aus dem NDC-Bereich (Normalized Device Coordinate) abgeleitet werden, der in diesem Kontext Vulkan-Konventionen verwendet: Der NDC-Bereich ist als [-1, -1, 0] bis [1, 1, 1] definiert und unterscheidet sich vom NDC-Bereich von OpenGL. Der Bewegungsvektor selbst ist jedoch nicht auf diesen Bereich beschränkt. Seine Werte hängen von der Bewegung des Pixels ab und können über die Grenzen des NDC-Bereichs hinausgehen. Wenn beispielsweise die NDC eines Pixels im vorherigen Frame „PrevNDC“ und im aktuellen Frame „CurrNDC“ ist und es keine Skalierung oder Verschiebung gibt, ist der Wert des Bewegungsvektors „(CurrNDC – PrevNDC) xyz“.

Gültige Verwendung (implizit)

Hinweis

Es gibt viele verschiedene Möglichkeiten, motionVectorSubImage und depthSubImage zu generieren. Die Anwendung kann sie beispielsweise in einem dedizierten Bewegungsvektor-Durchlauf mit niedrigerer Auflösung rendern (empfohlene Auflösung siehe XrFrameSynthesisConfigViewEXT) oder im Hauptansichtsdurchlauf mit MRT (Multiple Render Targets) rendern. Es liegt an der Anwendung, den spezifischen Ansatz zu bestimmen. Für motionVectorSubImage werden signierte 16-Bit-Gleitkommaformate pro Pixelkanal empfohlen.

Flags für die Frame-Synthese

typedef XrFlags64 XrFrameSynthesisInfoFlagsEXT;

// Flag bits for XrFrameSynthesisInfoFlagsEXT
static const XrFrameSynthesisInfoFlagsEXT XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT = 0x00000001;
static const XrFrameSynthesisInfoFlagsEXT XR_FRAME_SYNTHESIS_INFO_REQUEST_RELAXED_FRAME_INTERVAL_BIT_EXT = 0x00000002;

Flag-Beschreibungen

  • XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT gibt an, dass 2D-Bewegungsvektordaten verwendet werden.
  • XR_FRAME_SYNTHESIS_INFO_REQUEST_RELAXED_FRAME_INTERVAL_BIT_EXT gibt der Laufzeit einen Hinweis, dass die Anwendung mehr Zeit zum Rendern jedes Frames bevorzugt. Der Nachteil ist, dass mehr Frames von der Laufzeit synthetisiert werden. Dies kann für Anwendungen nützlich sein, bei denen die CPU- und GPU-Auslastung möglichst gering gehalten werden soll (z.B. für eine längere Akkulaufzeit) oder bei denen das Rechenbudget jedes Frames erhöht werden soll. Die Laufzeit kann Frames in beliebigen Intervallen anfordern, unabhängig vom Wert dieses Flags.

Standardmäßig erwartet die Laufzeit 3D-Bewegungsvektordaten. Daher werden motionVectorSubImage rgb, motionVectorScale xyz und motionVectorOffset xyz verwendet, wie in XrFrameSynthesisInfoEXT beschrieben.

Wenn XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT für XrFrameSynthesisInfoEXT layerFlags aktiviert ist, interpretiert die Laufzeit das eingereichte Bewegungsvektorbild stattdessen als 2D-Bewegungsvektordaten, die die 2D-Pixelbewegung vom vorherigen Frame zum aktuellen Frame darstellen. Pixelwerte werden für 2D-Bewegungsvektordaten so interpretiert: motionVector = motionVectorSubImage rg * motionVectorScale xy + motionVectorOffset xy . Die Komponenten motionVectorSubImage ba , motionVectorScale zw und motionVectorOffset zw werden ignoriert. Die Verwendung von 2D- statt 3D-Bewegungsvektordaten kann die Qualität der synthetisierten Frames beeinträchtigen.

Die Struktur XrFrameSynthesisConfigViewEXT ist so definiert:

typedef struct XrFrameSynthesisConfigViewEXT {
    XrStructureType    type;
    void*              next;
    uint32_t           recommendedMotionVectorImageRectWidth;
    uint32_t           recommendedMotionVectorImageRectHeight;
} XrFrameSynthesisConfigViewEXT;

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • recommendedMotionVectorImageRectWidth : Empfohlene Breite des Bewegungsvektors und des Tiefenbilds.
  • recommendedMotionVectorImageRectHeight : Empfohlene Höhe des Bewegungsvektors und des Tiefenbilds.

Wenn diese Erweiterung aktiviert ist, kann eine Anwendung beim Aufrufen von xrEnumerateViewConfigurationViews eine XrFrameSynthesisConfigViewEXT-Struktur in der XrViewConfigurationView :: next-Kette übergeben, um Informationen zur empfohlenen Auflösung des Bewegungsvektor-Images zu erhalten.

Gültige Verwendung (implizit)

Neue Gebäude

Neue Enum-Konstanten

  • XR_EXT_FRAME_SYNTHESIS_EXTENSION_NAME
  • XR_EXT_frame_synthesis_SPEC_VERSION
  • Erweiterung von XrStructureType :

    • XR_TYPE_FRAME_SYNTHESIS_CONFIG_VIEW_EXT
    • XR_TYPE_FRAME_SYNTHESIS_INFO_EXT

Probleme

Versionsverlauf

  • Version 1, 31.01.2022 (Jian Zhang)

    • Ursprüngliche Erweiterungsbeschreibung, konvertiert aus fb_space_warp
    • Zusammenarbeit mit Mitwirkenden, um die Erweiterungsschnittstellen zu optimieren.