XR_EXT_spatial_container_self_rendering

Name String

XR_EXT_spatial_container_self_rendering

Erweiterungstyp

Instanzerweiterung

Registrierte Durchwahl

814

Revision

1

Ratification Status

Nicht ratifiziert

Erweiterungs- und Versionsabhängigkeiten

XR_EXT_spatial_container

Datum der letzten Änderung

2026-08-06

IP-Status

Keine bekannten Ansprüche auf geistiges Eigentum.

Mitwirkende

Lachlan Ford, Google
Andreas Loeve Selvik, Meta Platforms
Adam Gousetis, Meta Platforms
Bjorn Swenson, LÖVR
Cass Everitt, Meta Platforms
Christian Kruse, Meta Platforms
Denny Rönngren, Varjo Technologies
Fredia Huya-Kouadio, Godot Engine
Jakob Bornecrantz, NVIDIA
Jared Finder, Google
Jonathan Wright, Meta Platforms
Jian Zhang, ByteDance
Kurtis Eveleigh, Qualcomm
Mauricio Narvaez, Meta Platforms
Nick Klingensmith, Qualcomm
Nikita Lutsenko, Meta Platforms
Praveen Babu J D, ByteDance
Rylie Pavlik, Collabora
Salar Khan, Google
Shuai Liu, ByteDance
Walter Luh, Meta Platforms
Yin Li, Microsoft

Übersicht

Diese Erweiterung definiert das „Self-Rendering“ für räumliche Container. Die Pixel eines selbst gerenderten räumlichen Containers werden alle von einer App generiert und mithilfe von Standard-OpenXR-Swapchains und ‑Kompositionsebenen an die Laufzeit übermittelt. Da räumliche Container nicht immer alle Pixel eines Bildschirms einnehmen, informiert die Laufzeitumgebung Apps über die empfohlene Auflösung und Ansichtskonfiguration jedes räumlichen Containers, damit Apps effizienter rendern können.

Diese Erweiterung in Kombination mit XR_EXT_spatial_container soll eine Obermenge der Funktionen des herkömmlichen OpenXR 1.x-Core-Composition-Layer-Renderings bieten. OpenXR 1.x-Laufzeiten, die grafisches Rendering und diese Erweiterung unterstützen, müssen XrSystemSpatialContainerPropertiesEXT :: supportsImmersive auf „true“ setzen, um anzugeben, dass sie immersive räumliche Container unterstützen.

Lebenszyklus des Renderings von räumlichen Containern

Wenn eine App das Self-Rendering für einen räumlichen Container verwenden möchte, setzt sie beim Aufruf von xrCreateSpatialContainerEXT XrSpatialContainerCreateInfoEXT :: graphicsPresentation auf XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT. Diese App kann dann verwalten, ob ein räumlicher Container aktiv gerendert wird, indem sie die Funktionen xrBeginSpatialContainerRenderingEXT und xrEndSpatialContainerRenderingEXT aufruft. Diese Funktionen ersetzen xrBeginSession und xrEndSession . Es handelt sich nicht um Vorgänge pro Frame, wie xrBeginFrame und xrEndFrame .

In jedem Frame durchläuft eine App die folgenden Schritte:

  • Rufen Sie xrWaitFrame und xrBeginFrame auf. Diese Funktionen haben keine containerspezifischen Strukturen und funktionieren wie in der Kernspezifikation.
  • Mit xrLocateSpatialContainerViewsEXT können Sie Ansichtsposen, Projektionsparameter und Rendering-Empfehlungen für alle räumlichen Container abrufen, die aktiv gerendert werden. Für jeden räumlichen Container meldet die Laufzeit, ob die zugehörigen Kompositionsebenen gerendert werden sollten, und empfiehlt eine Methode zum Rendern der Ebenen, indem XrSpatialContainerViewStateEXT ausgefüllt wird.
  • Pixel werden normal in Kompositionsebenen gerendert. Diese Vorgänge haben keine containerspezifischen Strukturen.
  • Reichen Sie Kompositionsebenen für alle räumlichen Container ein, die aktiv gerendert werden, indem Sie xrEndFrame aufrufen und XrSpatialContainerLayerFrameEndInfoEXT verketten.

Wenn ein XrSpatialContainerEXT-Handle gelöscht wird, wird es implizit aus dem aktiven Render-Set entfernt. Eine App darf einen räumlichen Container zerstören, auch wenn sie einen erfolgreichen Aufruf von xrBeginSpatialContainerRenderingEXT durchgeführt hat, der nicht mit einem entsprechenden Aufruf von xrEndSpatialContainerRenderingEXT verknüpft ist. Die Laufzeit muss sich so verhalten, als ob xrEndSpatialContainerRenderingEXT bei Bedarf früh in der Implementierung von xrDestroySpatialContainerEXT implizit aufgerufen wird, wenn sie erfolgreich zurückgegeben wird.

Wenn eine App ein XrEventDataSpatialContainerClosedEXT-Ereignis für einen Container im aktiven Rendering-Set empfängt, sollte sie xrEndSpatialContainerRenderingEXT aufrufen und das XrSpatialContainerEXT-Handle löschen.

Mit der Funktion xrBeginSpatialContainerRenderingEXT wird der räumliche Container dem aktiven Render-Set pro Sitzung hinzugefügt. So kann eine App Kompositionsebenen für den räumlichen Container an xrEndFrame senden.

XrResult xrBeginSpatialContainerRenderingEXT(
    XrSession                                   session,
    const XrSpatialContainerBeginInfoEXT*       beginInfo);

Parameterbeschreibungen

Apps rufen diese Funktion in der Regel als Reaktion auf ein „visible-changed“-Ereignis auf, bei dem XrEventDataSpatialContainerVisibleChangedEXT :: visible auf „true“ gesetzt ist.

Wenn der räumliche Container beim Aufruf von xrCreateSpatialContainerEXT nicht mit XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT erstellt wurde, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT zurückgeben.

Wenn sich der räumliche Container bereits im aktiven Render-Set befindet, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT zurückgeben.

Wenn xrBeginSpatialContainerRenderingEXT zu einem Zeitpunkt aufgerufen wird, zu dem die App xrWaitFrame nicht aufrufen konnte (also innerhalb des Fensters xrBeginFrame und xrEndFrame), muss die Laufzeit XR_ERROR_CALL_ORDER_INVALID zurückgeben.

Gültige Verwendung (implizit)

Threadsicherheit

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • XR_ERROR_CALL_ORDER_INVALID
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT
  • XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

Die Struktur XrSpatialContainerBeginInfoEXT wird verwendet, um die Parameter für den Beginn des Renderings eines räumlichen Containers anzugeben.

typedef struct XrSpatialContainerBeginInfoEXT {
    XrStructureType            type;
    const void*                next;
    XrSpatialContainerEXT      spatialContainer;
    XrViewConfigurationType    primaryViewConfigurationType;
} XrSpatialContainerBeginInfoEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • spatialContainer ist der XrSpatialContainerEXT, mit dem das Rendering gestartet werden soll.
  • primaryViewConfigurationType ist der primäre XrViewConfigurationType, der für den räumlichen Container verwendet werden soll.

primaryViewConfigurationType ist die Ansichtskonfiguration, die die App beim Rendern verwenden soll. Die Laufzeit kann die Ansichtskonfiguration zu Optimierungszwecken auf einen Typ mit weniger Ansichten reduzieren (z.B. wenn ein Container sehr weit entfernt und klein ist, sodass Stereo nicht wahrnehmbar ist). Die Laufzeit gibt Details zur veralteten Ansichtskonfiguration aus Aufrufen von xrLocateSpatialContainerViewsEXT zurück.

Gültige Verwendung (implizit)

Mit der Funktion xrEndSpatialContainerRenderingEXT wird der räumliche Container aus dem aktiven Rendering-Set entfernt.

XrResult xrEndSpatialContainerRenderingEXT(
    XrSession                                   session,
    const XrSpatialContainerEndInfoEXT*         endInfo);

Parameterbeschreibungen

Apps rufen diese Funktion in der Regel als Reaktion auf ein „visible-changed“-Ereignis auf, bei dem XrEventDataSpatialContainerVisibleChangedEXT :: visible auf „false“ gesetzt ist.

Wenn sich der räumliche Container nicht im aktiven Rendering-Set befindet, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT zurückgeben.

Wenn xrEndSpatialContainerRenderingEXT zu einem Zeitpunkt aufgerufen wird, an dem die App xrWaitFrame nicht aufrufen konnte (also zwischen den Aufrufen von xrBeginFrame und xrEndFrame), muss die Laufzeit XR_ERROR_CALL_ORDER_INVALID zurückgeben.

Gültige Verwendung (implizit)

Threadsicherheit

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • XR_ERROR_CALL_ORDER_INVALID
  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • XR_ERROR_VALIDATION_FAILURE

Die Struktur XrSpatialContainerEndInfoEXT wird verwendet, um die Parameter für das Beenden des Renderings eines räumlichen Containers anzugeben.

typedef struct XrSpatialContainerEndInfoEXT {
    XrStructureType          type;
    const void*              next;
    XrSpatialContainerEXT    spatialContainer;
} XrSpatialContainerEndInfoEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • spatialContainer ist der XrSpatialContainerEXT, für den das Rendering beendet werden soll.

Gültige Verwendung (implizit)

Ansichten über xrLocateSpatialContainerViewsEXT finden

Die Funktion xrLocateSpatialContainerViewsEXT sucht nach Ansichten für eine Reihe von räumlichen Containern.

XrResult xrLocateSpatialContainerViewsEXT(
    XrSession                                   session,
    const XrSpatialContainerViewsLocateInfoEXT* locateInfo,
    uint32_t                                    viewStateCount,
    XrSpatialContainerViewStateEXT*             viewStates,
    uint32_t                                    viewCount,
    XrView*                                     views);

Parameterbeschreibungen

Diese Funktion ersetzt xrLocateViews und ermöglicht es einer App, Ansichten für mehrere räumliche Container gleichzeitig abzufragen.

Ansichten für alle räumlichen Container werden im einzelnen views-Array zurückgegeben. Die Ansichten werden nach dem Index des räumlichen Containers im Array XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos und dann nach dem Ansichtsindex für diesen Container sortiert.

Wenn eine App beispielsweise drei räumliche Container in XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos bereitstellt:

  • Index 0: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO (1 Aufruf)
  • Index 1: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO (2 Aufrufe)
  • Index 2: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET (4 Aufrufe)

Anschließend muss die Laufzeit das Array views mit 7 Ansichten füllen:

  • views [0] ist die Ansicht für Container 0.
  • views [1] ist die Ansicht für das linke Auge für Container 1.
  • views [2] ist die Ansicht für das rechte Auge für Container 1.
  • views [3] ist die Ansicht für das linke Auge für Container 2.
  • views [4] ist die Ansicht für das rechte Auge für Container 2.
  • views [5] ist die Ansicht des linken Auges für Container 2.
  • views [6] ist die Ansicht des rechten Auges für Container 2.

Wenn viewCount nicht der Summe der Aufrufzahlen für den angeforderten Ansichtskonfigurationstyp jedes räumlichen Containers entspricht, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.

Die Laufzeit kann die Ansichtskonfiguration zu Optimierungszwecken auf einen Typ mit weniger Ansichten reduzieren (z.B. wenn ein Container sehr weit entfernt und klein ist, sodass Stereo nicht wahrnehmbar ist). Wenn die Laufzeit die Ansichtskonfiguration verfallen lässt, muss die Laufzeit trotzdem die ursprüngliche Anzahl von Ansichten für diesen Container zurückgeben und die zusätzlichen Ansichten mit Duplikaten der verfallenen Ansichten füllen. Wenn beispielsweise XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO auf XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO reduziert wird, enthalten sowohl Index 0 als auch Index 1 die einzelne Mono-Ansicht. Die Gesamtzahl der im Array views zurückgegebenen Ansichten ist daher unabhängig davon, ob die Laufzeitumgebung Ansichtskonfigurationen verfallen lässt oder nicht.

Die Laufzeit sollte jede zurückgegebene XrView :: fov so anpassen, dass der Frustum so klein wie möglich ist, aber dennoch die gesamten Grenzen des entsprechenden räumlichen Containers enthält. Laufzeiten können asymmetrische Sichtfelder zurückgeben, z. B. wenn ein räumlicher Container in einem schrägen Winkel zur Sicht des Nutzers steht oder teilweise von einem anderen Objekt verdeckt wird. Laufzeiten können die Ziel-Rendering-Oberfläche für den räumlichen Container frei positionieren. Aufgrund der Art des Multi-App-Renderings, bei dem räumliche Container vom Nutzer getrennt sind, kann die Laufzeit XrView-Werte zurückgeben, die nicht für das Pixel-Rendering geeignet sind. Wenn der räumliche Container beispielsweise nicht auf dem Bildschirm sichtbar ist, gibt es keine gültigen Werte, auf die XrView :: fov festgelegt werden kann. In solchen Fällen müssen Laufzeiten XrSpatialContainerViewStateEXT :: shouldSubmitLayers auf „false“ setzen.

Die Laufzeit gibt im Array viewStates zusätzliche Informationen zum Renderingstatus pro räumlichem Container zurück. Wenn viewStateCount nicht gleich XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.

Nachdem die Laufzeit ein XrEventDataSpatialContainerClosedEXT-Ereignis für einen räumlichen Container in die Warteschlange gestellt hat, muss diese Funktion XR_FALSE in XrSpatialContainerViewStateEXT :: shouldSubmitLayers und 0 in XrSpatialContainerViewStateEXT :: viewStateFlags für den entsprechenden räumlichen Container zurückgeben.

Bei räumlichen Containern mit sich aktiv ändernden Standorten in der realen Welt sollte die Laufzeit die Bewegung des Containers beim Ausfüllen von views berücksichtigen, um Reprojektionsartefakte zu minimieren.

Wenn xrLocateSpatialContainerViewsEXT für einen oder mehrere räumliche Container aufgerufen wird, die sich derzeit nicht im aktiven Render-Set befinden, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT zurückgeben.

Gültige Verwendung (implizit)

  • Die Erweiterung XR_EXT_spatial_container_self_rendering muss aktiviert werden, bevor xrLocateSpatialContainerViewsEXT aufgerufen wird.
  • session muss ein gültiges XrSession-Handle sein
  • locateInfo muss ein Zeiger auf eine gültige XrSpatialContainerViewsLocateInfoEXT-Struktur sein.
  • viewStates muss ein Zeiger auf ein Array von viewStateCount XrSpatialContainerViewStateEXT-Strukturen sein
  • views muss ein Zeiger auf ein Array von viewCount XrView-Strukturen sein.
  • Der Parameter viewStateCount muss größer als 0 sein.
  • Der Parameter viewCount muss größer als 0 sein.

Rückgabecodes

Erfolg

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Fehler

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SESSION_LOST
  • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • XR_ERROR_TIME_INVALID
  • XR_ERROR_VALIDATION_FAILURE
  • XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED

Die Struktur XrSpatialContainerViewsLocateInfoEXT enthält die Parameter zum Lokalisieren von Ansichten in einer Sammlung von räumlichen Containern.

typedef struct XrSpatialContainerViewsLocateInfoEXT {
    XrStructureType                               type;
    const void*                                   next;
    XrTime                                        displayTime;
    uint32_t                                      viewLocateInfoCount;
    const XrSpatialContainerViewLocateInfoEXT*    viewLocateInfos;
} XrSpatialContainerViewsLocateInfoEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • displayTime ist der XrTime, an dem sich die Ansichten befinden.
  • viewLocateInfoCount ist die Anzahl der Einträge im viewLocateInfos-Array.
  • viewLocateInfos ist ein Zeiger auf ein Array von XrSpatialContainerViewLocateInfoEXT-Strukturen.

Gültige Verwendung (implizit)

Die Struktur XrSpatialContainerViewLocateInfoEXT enthält die Parameter für einen einzelnen räumlichen Container, für den Ansichten gefunden werden sollen.

typedef struct XrSpatialContainerViewLocateInfoEXT {
    XrStructureType            type;
    const void*                next;
    XrViewConfigurationType    viewConfigurationType;
    XrSpace                    space;
    XrSpatialContainerEXT      spatialContainer;
} XrSpatialContainerViewLocateInfoEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • viewConfigurationType ist ein XrViewConfigurationType, der für den räumlichen Container verwendet werden soll.
  • space ist der XrSpace, in dem sich die Ansichten des räumlichen Containers befinden.
  • spatialContainer ist das XrSpatialContainerEXT-Handle.

Die App kann einen beliebigen gültigen XrSpace in space bereitstellen. Es wird jedoch empfohlen, den räumlichen Containerbereich für den entsprechenden XrSpatialContainerEXT bereitzustellen, der in der Struktur XrSpatialContainerViewLocateInfoEXT angegeben ist.

Gültige Verwendung (implizit)

Die Struktur XrSpatialContainerViewStateEXT wird durch Aufrufe von xrLocateSpatialContainerViewsEXT mit Informationen zur Rendering-Eignung pro räumlichem Container gefüllt.

typedef struct XrSpatialContainerViewStateEXT {
    XrStructureType            type;
    void*                      next;
    XrViewStateFlags           viewStateFlags;
    XrViewConfigurationType    viewConfigurationType;
    XrBool32                   shouldSubmitLayers;
    XrExtent2Di                recommendedImageExtent;
} XrSpatialContainerViewStateEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • viewStateFlags ist eine Bitmaske von XrViewStateFlags . Diese Flags haben denselben Zweck wie die viewStateFlags in der XrViewState-Kernstruktur.
  • viewConfigurationType ist ein XrViewConfigurationType, der den Ansichtskonfigurationstyp angibt, den die Laufzeit für den räumlichen Container verwendet. Laufzeiten können zu einer Ansichtskonfiguration mit einer geringeren Anzahl von Ansichten als der angeforderten herabgestuft werden.
  • shouldSubmitLayers ist ein XrBool32, der von der Laufzeit zurückgegeben wird. Wenn XR_FALSE, sollte die App das Senden von Kompositionen für diesen räumlichen Container vermeiden, da er derzeit nicht sichtbar ist oder sich in einem Zustand befindet, in dem kein Rendering erforderlich ist.
  • recommendedImageExtent ist eine XrExtent2Di-Struktur, die die empfohlene Auflösung für den räumlichen Container darstellt.

Wie bei der OpenXR-Kernansichtsposition muss die App XrSpatialContainerViewStateEXT :: viewStateFlags prüfen, um sicherzustellen, dass die Position und Ausrichtung gültig sind und erfasst werden, bevor die Ansichtsdaten für das Rendering verwendet werden.

Die App sollte shouldSubmitLayers und viewConfigurationType prüfen, um zu vermeiden, dass mehr gerendert wird, als von der Laufzeit empfohlen. Wenn shouldSubmitLayers „false“ ist, ändert die App ihr Renderingverhalten so:

  • Die App darf die entsprechende XrView :: fov nicht lesen.
  • Die App darf recommendedImageExtent nicht lesen.
  • Die App sollte das Rendern in Swapchains und das Senden von Kompositionsebenen für den entsprechenden räumlichen Container vermeiden.
  • Die App sollte XrSpatialContainerLayerEXT :: retainPreviousSubmission auf „true“ setzen. Wenn die App trotzdem Ebenen einreicht, entscheidet die Laufzeit, was mit den Ebenen geschehen soll (z.B. kann die Laufzeit sie verwerfen).

recommendedImageExtent ist explizit für Ebenen vorgesehen, die basierend auf der Containerposition oder der Ansicht des Nutzers aktualisiert werden. Wenn Ebenen mit Inhalten aktualisiert werden, die von der Position des räumlichen Containers oder der Ansicht des Nutzers abhängen (z. B. normale 3D-Inhalte), sollte die App in diesem kleineren Darstellungsbereich statt in der standardmäßig empfohlenen Ansichtsgröße rendern. Wenn Ebenen mit Inhalten aktualisiert werden, die nicht von der Position des räumlichen Containers oder der Ansicht des Nutzers abhängen (z. B. statische Quad-Ebenen), kann die App diese Werte ignorieren. Bei ansichtsabhängigen Ebenen ist recommendedImageExtent eine Empfehlung der Laufzeitumgebung an die App, um Aliasing zu minimieren und die Renderingleistung zu verbessern. Die App kann Bilder in voller Auflösung einreichen, wenn sie möchte.

XrExtent2Di :: width und XrExtent2Di :: height von recommendedImageExtent müssen immer eine positive Ganzzahl sein, die kleiner oder gleich XrViewConfigurationView :: recommendedImageRectWidth und XrViewConfigurationView :: recommendedImageRectHeight von XrViewConfigurationView für die primäre Ansichtskonfiguration des räumlichen Containers ist. Eine App sollte eine Swapchain nicht nur deshalb neu erstellen, weil sich recommendedImageExtent geändert hat. Es handelt sich dabei um einen dynamischen Hinweis für die App, der die XrSwapchainSubImage :: imageRect angibt, die in der XrSwapchainSubImage aller von ihr gesendeten Kompositionsebenen mit voller Auflösung verwendet werden soll, und kann sich bei jedem Frame ändern.

Gültige Verwendung (implizit)

Referenzbereich ansehen

Der Ansichtsreferenzraum bleibt unverändert, da er sich im OpenXR-Kern befindet. Wie bei der Kernvariante ist sie nicht für das Rendering vorgesehen.

Ebenen über xrEndFrame einreichen

Damit räumliche Container gerendert werden können, muss die App eine Liste der Ebenen, die mit den jeweiligen räumlichen Containern verknüpft sind, an xrEndFrame übergeben. Dies wird über die Struktur XrSpatialContainerLayerFrameEndInfoEXT erreicht.

typedef struct XrSpatialContainerLayerFrameEndInfoEXT {
    XrStructureType                      type;
    const void*                          next;
    uint32_t                             containerLayerCount;
    const XrSpatialContainerLayerEXT*    containerLayers;
} XrSpatialContainerLayerFrameEndInfoEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • containerLayerCount ist die Anzahl der Elemente im Array containerLayers.
  • containerLayers ist ein Zeiger auf ein Array von XrSpatialContainerLayerEXT-Strukturen.

Das containerLayers-Array enthält für jeden räumlichen Container im aktiven Rendering-Set (die Container, die pro Sitzung von xrBeginSpatialContainerRenderingEXT und xrEndSpatialContainerRenderingEXT verwaltet werden) einen XrSpatialContainerLayerEXT. Jede XrSpatialContainerLayerEXT enthält eine Liste von XrCompositionLayerBaseHeader-Zeigern, die mit dem jeweiligen räumlichen Container verknüpft sind. Laufzeiten können zusammengesetzte Container in beliebiger Reihenfolge erstellen, unabhängig von der Reihenfolge der containerLayers . Beispielsweise können Laufzeiten Container basierend auf ihrer Tiefe relativ zum Nutzer zusammensetzen, einen räumlichen Container als Hintergrundebene verwenden oder einen räumlichen Container so „anpinnen“, dass er unabhängig von seiner Tiefe immer oben ist. Laufzeiten können Ebenen mit unterschiedlichen Strategien für räumliche Container im begrenzten oder immersiven Modus zusammensetzen. Beispielsweise können Laufzeiten die Kompositionsebenen jedes begrenzten räumlichen Containers in einer einzigen Stereo-Quad-Ebene vorkomponieren, die in einem zweiten Kompositionsschritt mit allen anderen Containern kombiniert wird.

XrFrameEndInfo :: displayTime und XrFrameEndInfo :: environmentBlendMode werden auf alle räumlichen Container angewendet, die in XrSpatialContainerLayerFrameEndInfoEXT angegeben sind.

Wenn diese Struktur an xrEndFrame übergeben wird, indem sie mit XrFrameEndInfo verkettet wird, werden die folgenden zusätzlichen Fehlerfälle basierend auf dem aktiven Rendering-Set hinzugefügt:

  • Wenn ein räumlicher Container von mehr als einem Element von containerLayers referenziert wird, müssen Laufzeiten XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT zurückgeben.
  • Wenn ein räumlicher Container im aktiven Render-Set nicht von einem Element von containerLayers referenziert wird, müssen Laufzeiten XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT zurückgeben.
  • Wenn ein von containerLayers referenzierter räumlicher Container nicht Teil des aktiven Render-Sets ist, müssen Laufzeiten XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT zurückgeben.

Wenn sich im aktiven Rendering-Set räumliche Container befinden und diese Struktur nicht mit XrFrameEndInfo verkettet ist, müssen Laufzeiten XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT zurückgeben.

In allen oben genannten Fehlerfällen darf die Laufzeit keine Inhalte für räumliche Container rendern.

Wenn sich keine räumlichen Container im aktiven Rendering-Set befinden, kann eine App xrEndFrame aufrufen, solange sie keine Kompositionsebenen sendet.

Einzelne Swapchains können über Ebenen in einer gültigen Struktur für mehrere Container eingereicht werden, z.B. eine Quad-Ebene, die über eine einzelne Swapchain gerendert und an mehrere räumliche Container gesendet wird. Dieser Fall wird einheitlich mit anderen Renderings behandelt: Die Laufzeit muss das Quad in allen solchen räumlichen Containern rendern.

Gültige Verwendung (implizit)

Die XrSpatialContainerLayerEXT-Struktur gruppiert Standard-Kompositionsebenen und verknüpft sie mit einem bestimmten räumlichen Container.

typedef struct XrSpatialContainerLayerEXT {
    XrStructureType                               type;
    const void*                                   next;
    XrSpatialContainerEXT                         spatialContainer;
    XrBool32                                      retainPreviousSubmission;
    uint32_t                                      layerCount;
    const XrCompositionLayerBaseHeader* const*    layers;
} XrSpatialContainerLayerEXT;

Beschreibung des Mitglieds

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • spatialContainer ist der XrSpatialContainerEXT, der den Zielcontainer identifiziert.
  • retainPreviousSubmission ist ein XrBool32 . Wenn XR_TRUE , behält die Laufzeit den zuletzt gesendeten Frame für diesen räumlichen Container bei.
  • layerCount ist die Anzahl der Kompositionsebenen im Array layers.
  • layers ist ein Zeiger auf ein Array von XrCompositionLayerBaseHeader-Zeigern.

Wenn retainPreviousSubmission den Wert XR_TRUE hat, muss die Laufzeit die Kompositionsebenen und den Inhalt des Swapchain-Bildes wiederverwenden, wie sie während des letzten xrEndFrame-Aufrufs, bei dem retainPreviousSubmission den Wert XR_FALSE hatte, gespeichert wurden. Alle nachfolgenden Änderungen an Swapchains, die von beibehaltenen Ebenen verwendet werden, dürfen nicht in der gerenderten Ausgabe widergespiegelt werden.

Bei Ebenen, die für einen einzelnen räumlichen Container eingereicht werden (Intra-Container-Rendering), muss die Laufzeit die bereits festgelegten Regeln für die Reihenfolge der Ebenenzusammensetzung einhalten. Das bedeutet, dass die Ebenen innerhalb von Containern in derselben Reihenfolge gezeichnet werden müssen, in der sie angegeben sind, und zwar mithilfe des Painter-Algorithmus.

Das „Leeren“ eines räumlichen Containers bezieht sich auf das Entfernen aller Inhalte aus einem räumlichen Container, sodass im aktuellen Frame nichts für diesen Container gerendert wird. Laufzeiten müssen dies so behandeln, als würde die App für jeden Pixel im Container transparentes Schwarz (alle Bits 0) senden. „Beibehalten“ eines räumlichen Containers bedeutet, dass die Laufzeit weiterhin die zuletzt für diesen Container eingereichten Ebenen anzeigt.

Für jeden räumlichen Container kann die App angeben, ob neue Ebenen gesendet, die vorherige Einreichung beibehalten oder der räumliche Container gelöscht werden soll:

  • Um neue Ebenen einzureichen, stellt die App einen layerCount-Wert ungleich null und einen gültigen layers-Zeiger bereit.
  • Wenn Sie einen räumlichen Container löschen möchten, muss der layerCount für seinen Eintrag 0 und retainPreviousSubmission muss XR_FALSE sein.
  • Wenn die zuletzt gesendeten Ebenen und Swapchain-Bilder beibehalten werden sollen, muss layerCount für den Eintrag 0 und retainPreviousSubmission muss XR_TRUE sein.

Durch diese explizite Steuerung pro Container wird sichergestellt, dass die Absicht der App in jedem Frame klar kommuniziert wird.

Wenn retainPreviousSubmission XR_TRUE und layerCount nicht 0 ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.

Wenn XrSpatialContainerCompositionLayerViewConfigurationEXT nicht mit einer XrCompositionLayerProjection verkettet ist, die Teil eines räumlichen Containers ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben. Diese Struktur gilt nur für XrCompositionLayerProjection-Ebenen. Wenn sie mit anderen Ebenentypen (z.B. Quad- oder Zylinderebenen) verkettet ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.

Gültige Verwendung (implizit)

Ansichtskonfiguration für Projektionsebenen angeben

Mit der Struktur XrSpatialContainerCompositionLayerViewConfigurationEXT wird die Ansichtskonfiguration angegeben, die zum Rendern einer Projektionsebene für einen räumlichen Container verwendet wird.

typedef struct XrSpatialContainerCompositionLayerViewConfigurationEXT {
    XrStructureType            type;
    const void*                next;
    XrViewConfigurationType    viewConfigurationType;
} XrSpatialContainerCompositionLayerViewConfigurationEXT;

Beschreibung des Mitglieds

Wenn eine XrCompositionLayerProjection für einen räumlichen Container eingereicht wird, muss die App angeben, welche Ansichtskonfiguration zum Rendern der Ebene verwendet wurde. Das ist erforderlich, weil die App für jeden Frame entscheiden kann, ob sie mit der primären Ansichtskonfiguration des räumlichen Containers oder mit der von der Laufzeit vorgeschlagenen, gegebenenfalls abgeschwächten Ansichtskonfiguration gerendert werden soll.

Wenn XrSpatialContainerCompositionLayerViewConfigurationEXT verkettet ist, muss die App dafür sorgen, dass XrCompositionLayerProjection :: viewCount eine gültige Anzahl von Ansichten für den in der verketteten Struktur angegebenen XrViewConfigurationType ist. Der in der verketteten Struktur angegebene viewConfigurationType muss der XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType sein, der beim Start des Containers angegeben wurde, oder der von der Laufzeit in XrSpatialContainerViewStateEXT zurückgegebene Typ der veralteten Ansichtskonfiguration oder zusätzliche Werte, die über eine Erweiterung aktiviert wurden.

Gültige Verwendung (implizit)

Pixel-Clipping-Verhalten

Apps sollten die Laufzeit darüber informieren, ob sie Pixel außerhalb der Grenzen eines räumlichen Containers rendern oder nicht. Dazu müssen sie beim Senden von Kompositionsebenen XrSpatialContainerLayerVolumeClippingEXT verketten.

typedef struct XrSpatialContainerLayerVolumeClippingEXT {
    XrStructureType                        type;
    const void*                            next;
    XrSpatialContainerVolumeClippingEXT    volumeClipping;
} XrSpatialContainerLayerVolumeClippingEXT;

Beschreibung des Mitglieds

Diese Struktur dient als Hinweis darauf, ob die App Pixel außerhalb der Grenzen eines räumlichen Containers rendert. Wenn sich ein räumlicher Container im immersiven Modus befindet, hat dieser Hinweis keine Bedeutung, da die Grenzen unendlich sind.

Bei begrenzten räumlichen Containern mit Self-Rendering muss die Laufzeit sowohl die 3D-Volumengrenzen als auch die 2D-Pixelgrenzen berücksichtigen. Die 3D-Volumengrenzen werden von xrGetSpatialContainerBoundsEXT zurückgegeben. Die 2D-Pixelgrenzen sind die Projektion der 3D-Volumengrenzen auf jedes Display des Systems.

Laufzeiten müssen Pixel aus Swapchain-Bildern außerhalb der 2D-Pixelgrenzen verwerfen. Laufzeiten dürfen jedoch keine Pixel verwerfen, die sich innerhalb der 2D-Pixelgrenzen, aber außerhalb der 3D-Volumengrenzen befinden. Stereoeffekte, bei denen Inhalte über die 3D-Volumengrenzen des Containers hinaus oder davor zu ragen scheinen, sind möglich. Apps können Pixel außerhalb der 3D-Volumengrenzen eines begrenzten räumlichen Containers verwerfen, um Tiefenparadoxa zu reduzieren, und sollten volumeClipping entsprechend festlegen. Tiefenparadoxa führen oft zu einer Überanstrengung der Augen und Unbehagen bei Nutzern.

Laufzeiten können volumeClipping verwenden, um die Darstellung eines bestimmten räumlichen Containers anzupassen. Wenn beispielsweise XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT festgelegt ist, kann eine Laufzeit die Rückseiten der 3D-Volumengrenzen rendern, was zu Tiefenparadoxen führen würde, wenn der räumliche Container Pixel hinter den 3D-Volumengrenzen des Containers zeichnet.

Zukünftige Erweiterungen könnten das Clipping basierend auf den 3D-Volumengrenzen ermöglichen, wenn Tiefeninformationen übermittelt werden.

Gültige Verwendung (implizit)

Neue Befehle

Neue Gebäude

Neue Enum-Konstanten

  • XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME
  • XR_EXT_spatial_container_self_rendering_SPEC_VERSION
  • Erweiterung von XrResult :

    • XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT
    • XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT
    • XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
  • Erweiterung von XrSpatialContainerGraphicsPresentationEXT :

    • XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
  • Erweiterung von XrStructureType :

    • XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT
    • XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT
    • XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT

Codebeispiele

// Example: Complete lifecycle, view location, and frame submission for spatial containers
PFN_xrBeginSpatialContainerRenderingEXT xrBeginSpatialContainerRenderingEXT; // previously initialized
PFN_xrEndSpatialContainerRenderingEXT xrEndSpatialContainerRenderingEXT; // previously initialized
PFN_xrLocateSpatialContainerViewsEXT xrLocateSpatialContainerViewsEXT; // previously initialized

XrSession session; // previously initialized

// We want to update this container
XrSpatialContainerEXT containerA; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerASpace; // previously initialized

// We want to retain this container
XrSpatialContainerEXT containerB; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerBSpace; // previously initialized

// 1. Add to active render set when the app is ready to start submitting layers
XrSpatialContainerBeginInfoEXT beginInfoA {
  .type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
  .spatialContainer = containerA,
  .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoA));

XrSpatialContainerBeginInfoEXT beginInfoB {
  .type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
  .spatialContainer = containerB,
  .primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoB));

// ... Frame Loop ...


XrTime displayTime; // returned from xrWaitFrame

const std::vector<XrSpatialContainerEXT> containers = {containerA, containerB};
const std::vector<XrSpace> containerSpaces = {containerASpace, containerBSpace};
uint32_t containerCount = static_cast<uint32_t>(containers.size());

// 2. Setup individual locate info for each container
std::vector<XrSpatialContainerViewLocateInfoEXT> containerLocateInfos(containerCount, {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT,
});

for (uint32_t i = 0; i < containerCount; ++i) {
    containerLocateInfos[i].viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
    containerLocateInfos[i].space = containerSpaces[i]; // Recommended to use container's own space
    containerLocateInfos[i].spatialContainer = containers[i];
}

// Setup bulk locate info
XrSpatialContainerViewsLocateInfoEXT locateInfo {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT,
  .displayTime = displayTime,
  .viewLocateInfoCount = containerCount,
  .viewLocateInfos = containerLocateInfos.data(),
};

// Prepare states to be populated by the runtime
std::vector<XrSpatialContainerViewStateEXT> viewStates(containerCount, {
  .type = XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT,
});

// Call the dedicated locate views function
// We know the required view count is 2 per container for STEREO
const uint32_t viewsPerConfig = 2;
uint32_t totalViewCount = containerCount * viewsPerConfig;
std::vector<XrView> views(totalViewCount, {.type = XR_TYPE_VIEW});

CHK_XR(xrLocateSpatialContainerViewsEXT(session, &locateInfo, containerCount, viewStates.data(), totalViewCount, views.data()));

// Process results
for (uint32_t i = 0; i < containerCount; ++i) {
    XrBool32 shouldSubmitLayers = viewStates[i].shouldSubmitLayers;
    XrExtent2Di recommendedImageExtent = viewStates[i].recommendedImageExtent;
    XrViewConfigurationType viewConfigurationType = viewStates[i].viewConfigurationType;
    bool isDecayedToMono = (viewConfigurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO);
    if (shouldSubmitLayers) {
        // App is expected to also verify viewStates[i].viewStateFlags has valid orientation/position bits before rendering
        XrView& leftView = views[i * viewsPerConfig];
        XrView& rightView = views[i * viewsPerConfig + 1];
        // If isDecayedToMono is true, left and right will be identical.
    } else {
        // Skip layer submission but retain previous submission when calling
        // xrEndFrame.
    }
}

// 3. Setup projection layer for container A
XrCompositionLayerProjection projectionLayer = {.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION};
// ... standard projection layer setup (space, viewCount, views, etc.) ...

// Specify which view configuration was used to render this specific layer
XrSpatialContainerCompositionLayerViewConfigurationEXT containerViewConfig {
  .type = XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT,
  // Even if the runtime decayed to MONO, we indicate what we actually rendered
  .viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};

// Chain it to the projection layer
projectionLayer.next = &containerViewConfig;
const XrCompositionLayerBaseHeader* layersA[1] = {reinterpret_cast<const XrCompositionLayerBaseHeader*>(&projectionLayer)};

// Note: In a real app, you are required to submit ALL active containers in the render set.

XrSpatialContainerLayerVolumeClippingEXT containerClippingA = {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
  // Set volumeClipping appropriately for the rendering done.
  .volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};

// Setup container A (Update with new pixels)
XrSpatialContainerLayerEXT containerLayerA {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
  .next = &containerClippingA,
  .spatialContainer = containerA,
  .retainPreviousSubmission = XR_FALSE,
  .layerCount = 1,
  .layers = layersA,
};

XrSpatialContainerLayerVolumeClippingEXT containerClippingB {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
  // Set volumeClipping appropriately for the rendering done.
  .volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};

// Setup container B (Explicitly retain previous frame)
XrSpatialContainerLayerEXT containerLayerB {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
  .next = &containerClippingB,
  .spatialContainer = containerB,
  .retainPreviousSubmission = XR_TRUE,
  .layerCount = 0, // Required to be 0 when retaining
  .layers = nullptr,
};

// Aggregate all container layers
XrSpatialContainerLayerEXT containerLayers[] = { containerLayerA, containerLayerB };

XrSpatialContainerLayerFrameEndInfoEXT spatialEndInfo {
  .type = XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT,
  .containerLayerCount = 2, // Must equal the number of active containers
  .containerLayers = containerLayers,
};

XrFrameEndInfo frameEndInfo {
  .type = XR_TYPE_FRAME_END_INFO,
  .next = &spatialEndInfo,
  .displayTime = displayTime,
  .environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND,
  .layerCount = 0, // MANDATORY: Must be 0 for self rendering extension
};

CHK_XR(xrEndFrame(session, &frameEndInfo));

// ... End Frame Loop ...

// 4. Remove from active render set when the container is destroyed or no longer needs rendering
XrSpatialContainerEndInfoEXT endInfoA {
  .type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
  .spatialContainer = containerA,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoA));

XrSpatialContainerEndInfoEXT endInfoB {
  .type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
  .spatialContainer = containerB,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoB));

Versionsverlauf

  • Version 1, 06.08.2026 (Lachlan Ford)

    • Anfängliche Beschreibung der Erweiterung