XR_EXT_spatial_container_self_rendering

Name String

XR_EXT_spatial_container_self_rendering

Typ rozszerzenia

Rozszerzenie instancji

Zarejestrowany numer wewnętrzny

814

Wersja

1

Stan ratyfikacji

Nie ratyfikowano

Zależności rozszerzeń i wersji

XR_EXT_spatial_container

Data ostatniej modyfikacji

2026-08-06

Stan IP

Brak znanych roszczeń dotyczących własności intelektualnej.

Twórcy

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

Przegląd

To rozszerzenie definiuje „samodzielne renderowanie” w przypadku kontenerów przestrzennych. Piksele samodzielnie renderowanego kontenera przestrzennego są generowane przez aplikację i przesyłane do środowiska wykonawczego za pomocą standardowych łańcuchów wymiany i warstw kompozycji OpenXR. Kontenery przestrzenne nie zawsze zajmują wszystkie piksele ekranu, dlatego środowisko wykonawcze informuje aplikacje o zalecanej rozdzielczości i konfiguracji widoku każdego kontenera przestrzennego, aby umożliwić im wydajniejsze renderowanie.

To rozszerzenie w połączeniu z XR_EXT_spatial_container ma oferować superset możliwości konwencjonalnego renderowania warstwy kompozycji OpenXR 1.x. Środowiska wykonawcze OpenXR 1.x, które obsługują renderowanie graficzne i to rozszerzenie, muszą ustawić właściwość XrSystemSpatialContainerPropertiesEXT :: supportsImmersive na wartość „true”, aby wskazać, że obsługują immersyjne kontenery przestrzenne.

Cykl życia renderowania kontenera przestrzennego

Aby używać samodzielnego renderowania w przypadku kontenera przestrzennego, aplikacja ustawia XrSpatialContainerCreateInfoEXT :: graphicsPresentation na XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT podczas wywoływania xrCreateSpatialContainerEXT . Następnie aplikacja może zarządzać tym, czy kontener przestrzenny jest aktywnie renderowany, wywołując funkcje xrBeginSpatialContainerRenderingEXT i xrEndSpatialContainerRenderingEXT. Te funkcje zastępują xrBeginSession i xrEndSession . Nie są to operacje wykonywane na klatkę, takie jak xrBeginFrame i xrEndFrame .

W każdej klatce aplikacja wykonuje te czynności:

  • Wywołaj xrWaitFrame i xrBeginFrame . Te funkcje nie mają struktur specyficznych dla kontenera i działają tak samo jak w podstawowej specyfikacji.
  • Pobieraj pozycje widoku, parametry projekcji i rekomendacje dotyczące renderowania dla wszystkich kontenerów przestrzennych aktywnie renderowanych za pomocą xrLocateSpatialContainerViewsEXT . W przypadku każdego kontenera przestrzennego środowisko wykonawcze zgłasza, czy jego warstwy kompozycji powinny być renderowane, oraz zalecany sposób renderowania warstw, wypełniając XrSpatialContainerViewStateEXT .
  • Renderuj piksele w warstwach kompozycji w normalny sposób. Te operacje nie mają struktur specyficznych dla kontenera.
  • Prześlij warstwy kompozycji dla wszystkich kontenerów przestrzennych, które są aktywnie renderowane, wywołując funkcję xrEndFrame i tworząc łańcuch XrSpatialContainerLayerFrameEndInfoEXT .

Zniszczenie uchwytu XrSpatialContainerEXT powoduje jego niejawne usunięcie z aktywnego zestawu renderowania. Aplikacja może zniszczyć kontener przestrzenny, nawet jeśli pomyślnie wywołała funkcję xrBeginSpatialContainerRenderingEXT, która nie jest powiązana z odpowiednim wywołaniem funkcji xrEndSpatialContainerRenderingEXT . Środowisko wykonawcze musi zachowywać się tak, jakby funkcja xrEndSpatialContainerRenderingEXT była wywoływana niejawnie, jeśli jest to konieczne na wczesnym etapie implementacji funkcji xrDestroySpatialContainerEXT, jeśli zwraca ona wartość powodzenia.

Gdy aplikacja otrzyma zdarzenie XrEventDataSpatialContainerClosedEXT dla kontenera w aktywnym zbiorze renderowania, powinna wywołać xrEndSpatialContainerRenderingEXT i zniszczyć uchwyt XrSpatialContainerEXT.

Funkcja xrBeginSpatialContainerRenderingEXT dodaje kontener przestrzenny do aktywnego zestawu renderowania na sesję, co umożliwia aplikacji przesyłanie warstw kompozycji kontenera przestrzennego do xrEndFrame .

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

Opisy parametrów

Aplikacje zwykle wywołują tę funkcję w odpowiedzi na zdarzenie visible-changed z XrEventDataSpatialContainerVisibleChangedEXT :: visible ustawionym na wartość „true”.

Jeśli kontener przestrzenny nie został utworzony za pomocą XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT podczas wywoływania xrCreateSpatialContainerEXT , środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT .

Jeśli kontener przestrzenny znajduje się już w aktywnym zbiorze renderowania, środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT .

Jeśli funkcja xrBeginSpatialContainerRenderingEXT zostanie wywołana w momencie, gdy aplikacja nie może wywołać funkcji xrWaitFrame (czyli w oknie xrBeginFrame i xrEndFrame), środowisko wykonawcze musi zwrócić XR_ERROR_CALL_ORDER_INVALID.

Prawidłowe użycie (pośrednie)

Bezpieczeństwo wątków

Kody zwrotu

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • 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

Struktura XrSpatialContainerBeginInfoEXT służy do określania parametrów rozpoczęcia renderowania kontenera przestrzennego.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • spatialContainer to XrSpatialContainerEXT, który ma rozpocząć renderowanie.
  • primaryViewConfigurationType to główny typ XrViewConfigurationType, który ma być używany w kontenerze przestrzennym.

primaryViewConfigurationType to konfiguracja widoku, której aplikacja zamierza używać podczas renderowania. Środowisko wykonawcze może zmienić konfigurację widoku na typ z mniejszą liczbą widoków w celu optymalizacji (np. kontener jest bardzo daleko i jest mały, więc stereo jest niezauważalne). Środowisko wykonawcze zwraca szczegółowe informacje o konfiguracji widoku z zanikiem z wywołań xrLocateSpatialContainerViewsEXT .

Prawidłowe użycie (pośrednie)

Funkcja xrEndSpatialContainerRenderingEXT usuwa kontener przestrzenny z aktywnego zestawu renderowania.

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

Opisy parametrów

Aplikacje zwykle wywołują tę funkcję w odpowiedzi na zdarzenie visible-changed, gdy parametr XrEventDataSpatialContainerVisibleChangedEXT :: visible ma wartość false.

Jeśli kontener przestrzenny nie znajduje się w aktywnym zbiorze renderowania, środowisko wykonawcze musi zwrócić wartość XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Jeśli funkcja xrEndSpatialContainerRenderingEXT zostanie wywołana w momencie, gdy aplikacja nie może wywołać funkcji xrWaitFrame (czyli w okresie między wywołaniami funkcji xrBeginFrame i xrEndFrame), środowisko wykonawcze musi zwrócić XR_ERROR_CALL_ORDER_INVALID.

Prawidłowe użycie (pośrednie)

Bezpieczeństwo wątków

Kody zwrotu

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • 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

Struktura XrSpatialContainerEndInfoEXT służy do określania parametrów zakończenia renderowania kontenera przestrzennego.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • spatialContainer to XrSpatialContainerEXT, który ma zakończyć renderowanie.

Prawidłowe użycie (pośrednie)

Lokalizowanie widoków za pomocą xrLocateSpatialContainerViewsEXT

Funkcja xrLocateSpatialContainerViewsEXT lokalizuje widoki dla zestawu kontenerów przestrzennych.

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

Opisy parametrów

Ta funkcja zastępuje xrLocateViews , umożliwiając aplikacji wysyłanie zapytań o widoki dla wielu kontenerów przestrzennych jednocześnie.

Widoki wszystkich kontenerów przestrzennych są zwracane w jednej tablicy views. Widoki są uporządkowane według indeksu kontenera przestrzennego w tablicy XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos, a następnie według indeksu widoku dla tego kontenera.

Jeśli na przykład aplikacja udostępnia 3 kontenery przestrzenne w XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos :

  • Indeks 0: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO (1 widok)
  • Indeks 1: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO (2 widoki)
  • Indeks 2: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET (4 widoki)

Następnie środowisko wykonawcze musi wypełnić tablicę views 7 widokami:

  • views [0] to widok kontenera 0.
  • views [1] to widok dla lewego oka w kontenerze 1.
  • views [2] to widok z prawego oka dla kontenera 1.
  • views [3] to widok dla lewego oka w kontenerze 2.
  • views [4] to widok z prawej strony dla kontenera 2.
  • views [5] to widok wstawki lewego oka dla kontenera 2.
  • views [6] to widok wstawki prawego oka dla kontenera 2.

Jeśli wartość viewCount nie jest równa sumie liczby wyświetleń dla każdego typu konfiguracji widoku żądanego przez kontener przestrzenny, środowisko wykonawcze musi zwrócić wartość XR_ERROR_VALIDATION_FAILURE .

Środowisko wykonawcze może w celach optymalizacyjnych zmienić konfigurację widoku na typ z mniejszą liczbą widoków (np. kontener jest bardzo daleko i jest mały, więc stereo jest niezauważalne). Jeśli środowisko wykonawcze zmniejszy konfigurację widoku, musi nadal zwracać pierwotną liczbę widoków dla tego kontenera, wypełniając dodatkowe widoki duplikatami zmniejszonych widoków. Jeśli na przykład XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO zostanie przekształcony w XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO, zarówno indeks 0, jak i indeks 1 będą zawierać pojedynczy widok mono. W związku z tym łączna liczba wyświetleń zwrócona w tablicy views jest niezależna od tego, czy środowisko wykonawcze zdecydowało się na wygaszenie konfiguracji widoku.

Środowisko wykonawcze powinno dostosować każdy zwrócony obiekt XrView :: fov tak, aby ostrosłup ścięty był jak najmniejszy, ale nadal zawierał całe granice odpowiedniego kontenera przestrzennego. Środowiska wykonawcze mogą zwracać niesymetryczne pola widzenia, na przykład jeśli kontener przestrzenny jest ustawiony pod kątem do widoku użytkownika lub jest częściowo zasłonięty przez inny obiekt. Środowiska wykonawcze mogą dowolnie pozycjonować docelową powierzchnię renderowania kontenera przestrzennego. Ze względu na charakter renderowania wielu aplikacji, w którym kontenery przestrzenne są odłączone od użytkownika, środowisko wykonawcze może zwracać wartości XrView, które nie nadają się do renderowania pikseli. Jeśli na przykład kontener przestrzenny nie jest widoczny na ekranie, nie ma prawidłowych wartości, które można ustawić dla XrView :: fov. W takich przypadkach środowiska wykonawcze muszą ustawić XrSpatialContainerViewStateEXT :: shouldSubmitLayers na wartość „false”.

Środowisko wykonawcze zwraca dodatkowe informacje o stanie renderowania poszczególnych kontenerów przestrzennych w tablicy viewStates. Jeśli viewStateCount nie jest równe XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount , środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE .

Gdy środowisko wykonawcze doda do kolejki zdarzenie XrEventDataSpatialContainerClosedEXT dla kontenera przestrzennego, ta funkcja musi zwracać XR_FALSE w XrSpatialContainerViewStateEXT :: shouldSubmitLayers i 0 w XrSpatialContainerViewStateEXT :: viewStateFlags dla odpowiedniego kontenera przestrzennego.

W przypadku kontenerów przestrzennych, których lokalizacja w świecie rzeczywistym aktywnie się zmienia, środowisko wykonawcze powinno uwzględniać ruch kontenera podczas wypełniania pola views, aby zminimalizować artefakty reprojekcji.

Jeśli funkcja xrLocateSpatialContainerViewsEXT zostanie wywołana w przypadku co najmniej 1 kontenera przestrzennego, który nie znajduje się obecnie w aktywnym zbiorze renderowania, środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Prawidłowe użycie (pośrednie)

Kody zwrotu

Sukces

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Błąd

  • 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

Struktura XrSpatialContainerViewsLocateInfoEXT zawiera parametry do lokalizowania widoków w kolekcji kontenerów przestrzennych.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • displayTime to XrTime, w którym znajdują się widoki.
  • viewLocateInfoCount to liczba wpisów w tablicy viewLocateInfos.
  • viewLocateInfos to wskaźnik do tablicy struktur XrSpatialContainerViewLocateInfoEXT.

Prawidłowe użycie (pośrednie)

Struktura XrSpatialContainerViewLocateInfoEXT zawiera parametry pojedynczego kontenera przestrzennego, dla którego mają zostać zlokalizowane widoki.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • viewConfigurationType to XrViewConfigurationType, który ma być używany w przypadku kontenera przestrzennego.
  • space to XrSpace, w której znajdują się widoki kontenera przestrzennego.
  • spatialContainer to uchwyt XrSpatialContainerEXT.

Aplikacja może udostępniać dowolną prawidłową przestrzeń XrSpace w space, ale zalecamy, aby udostępniała przestrzeń kontenera przestrzennego dla odpowiedniego elementu XrSpatialContainerEXT określonego w strukturze XrSpatialContainerViewLocateInfoEXT.

Prawidłowe użycie (pośrednie)

Struktura XrSpatialContainerViewStateEXT jest wypełniana przez wywołania funkcji xrLocateSpatialContainerViewsEXT z informacjami o przydatności renderowania poszczególnych kontenerów przestrzennych.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • viewStateFlags to maska bitowa XrViewStateFlags . Te flagi mają ten sam cel co viewStateFlags w podstawowej strukturze XrViewState.
  • viewConfigurationType to XrViewConfigurationType, który wskazuje typ konfiguracji widoku używany przez środowisko wykonawcze dla kontenera przestrzennego. Środowiska wykonawcze mogą obniżyć konfigurację widoku do konfiguracji z mniejszą liczbą widoków niż żądana.
  • shouldSubmitLayers to XrBool32 zwracany przez środowisko wykonawcze. Jeśli XR_FALSE, aplikacja powinna unikać przesyłania kompozycji dla tego kontenera przestrzennego, ponieważ nie jest on obecnie widoczny lub jest w stanie, w którym renderowanie nie jest wymagane.
  • recommendedImageExtent to struktura XrExtent2Di reprezentująca zalecaną rozdzielczość kontenera przestrzennego.

Podobnie jak w przypadku podstawowej lokalizacji widoku OpenXR, aplikacja musi sprawdzić XrSpatialContainerViewStateEXT :: viewStateFlags, aby upewnić się, że pozycja i orientacja są prawidłowe i śledzone, zanim użyje danych widoku do renderowania.

Aplikacja powinna sprawdzać shouldSubmitLayers i viewConfigurationType, aby nie renderować więcej, niż zaleca środowisko wykonawcze. Gdy wartość shouldSubmitLayers jest fałszywa, aplikacja zmienia sposób renderowania w następujący sposób:

  • Aplikacja nie może odczytywać odpowiedniego elementu XrView :: fov .
  • Aplikacja nie może odczytywać danych recommendedImageExtent .
  • Aplikacja powinna unikać renderowania do łańcuchów wymiany i przesyłania warstw kompozycji dla odpowiedniego kontenera przestrzennego.
  • Aplikacja powinna ustawić XrSpatialContainerLayerEXT :: retainPreviousSubmission na wartość „true”. Jeśli aplikacja zdecyduje się mimo to przesłać warstwy, środowisko wykonawcze określi, co chce z nimi zrobić (np. może je odrzucić).

recommendedImageExtent jest przeznaczony wyłącznie dla warstw, które będą aktualizowane na podstawie pozycji kontenera lub widoku użytkownika. Podczas aktualizowania warstw treściami, które zależą od pozycji kontenera przestrzennego lub widoku użytkownika (np. zwykłe treści 3D), aplikacja powinna renderować je w tym mniejszym obszarze widocznym zamiast w domyślnym zalecanym rozmiarze widoku. Podczas aktualizowania warstw z treścią, która nie zależy od pozycji kontenera przestrzennego ani widoku użytkownika (np. statyczne warstwy quad), aplikacja może bezpiecznie ignorować te wartości. W przypadku warstw zależnych od widoku recommendedImageExtent to zalecenie dla aplikacji ze środowiska wykonawczego, które ma na celu zminimalizowanie aliasingu i poprawę wydajności renderowania. Aplikacja może przesłać obraz w pełnej rozdzielczości, jeśli jest taka potrzeba.

Wartości XrExtent2Di :: width i XrExtent2Di :: height elementu recommendedImageExtent muszą zawsze być dodatnią liczbą całkowitą mniejszą lub równą wartościom XrViewConfigurationView :: recommendedImageRectWidth i XrViewConfigurationView :: recommendedImageRectHeight elementu XrViewConfigurationView dla konfiguracji widoku głównego kontenera przestrzennego. Aplikacja nie powinna odtwarzać łańcucha wymiany tylko dlatego, że zmieniła się wartość recommendedImageExtent, ponieważ jest to dynamiczna wskazówka dla aplikacji określająca wartość XrSwapchainSubImage :: imageRect do użycia w XrSwapchainSubImage dowolnych przesyłanych warstw kompozycji o pełnej rozdzielczości i może zmieniać się w każdej klatce.

Prawidłowe użycie (pośrednie)

Wyświetl pokój referencyjny

Przestrzeń odniesienia widoku pozostaje niezmieniona, ponieważ znajduje się w OpenXR Core. Podobnie jak w przypadku rdzenia, nie jest on przeznaczony do renderowania.

Przesyłanie warstw za pomocą xrEndFrame

Aby renderować kontenery przestrzenne, aplikacja musi dostarczyć do xrEndFrame listę warstw powiązanych z odpowiednimi kontenerami przestrzennymi. Służy do tego struktura XrSpatialContainerLayerFrameEndInfoEXT.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • containerLayerCount to liczba elementów w tablicy containerLayers.
  • containerLayers to wskaźnik do tablicy struktur XrSpatialContainerLayerEXT.

Tablica containerLayers zawiera element XrSpatialContainerLayerEXT dla każdego kontenera przestrzennego w aktywnym zestawie renderowania (kontenery zarządzane na sesję przez xrBeginSpatialContainerRenderingEXT i xrEndSpatialContainerRenderingEXT). Każdy element XrSpatialContainerLayerEXT zawiera listę wskaźników XrCompositionLayerBaseHeader powiązanych z danym kontenerem przestrzennym. Środowiska wykonawcze mogą tworzyć kontenery w dowolnej kolejności, niezależnie od kolejności containerLayers . Na przykład środowiska wykonawcze mogą tworzyć kontenery na podstawie ich głębokości względem użytkownika, używać kontenera przestrzennego jako warstwy tła lub „przypinać” kontener przestrzenny, tak aby zawsze znajdował się na górze, niezależnie od głębokości. Środowiska wykonawcze mogą tworzyć warstwy kompozytowe przy użyciu różnych strategii dla kontenerów przestrzennych w trybach ograniczonym lub trybie imersji. Na przykład środowiska wykonawcze mogą wstępnie składać warstwy kompozycji każdego ograniczonego kontenera przestrzennego w jedną warstwę stereo quad, która jest łączona ze wszystkimi innymi kontenerami w drugim kroku kompozycji.

XrFrameEndInfo :: displayTime i XrFrameEndInfo :: environmentBlendMode zostaną zastosowane do wszystkich kontenerów przestrzennych dostarczonych w XrSpatialContainerLayerFrameEndInfoEXT .

Gdy ta struktura jest przekazywana do xrEndFrame przez połączenie z XrFrameEndInfo , dodawane są te dodatkowe przypadki błędów na podstawie aktywnego zestawu renderowania:

  • Jeśli do kontenera przestrzennego odwołuje się więcej niż 1 element containerLayers , środowiska wykonawcze muszą zwracać XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT .
  • Jeśli element containerLayers nie odwołuje się do kontenera przestrzennego w aktywnym zestawie renderowania, środowiska wykonawcze muszą zwracać XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .
  • Jeśli kontener przestrzenny, do którego odwołuje się containerLayers, nie należy do aktywnego zestawu renderowania, środowiska wykonawcze muszą zwracać XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Ponadto, jeśli w aktywnym zestawie renderowania znajdują się kontenery przestrzenne, a ta struktura nie jest połączona z XrFrameEndInfo, środowiska wykonawcze muszą zwracać XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .

W przypadku wystąpienia dowolnego z powyższych błędów środowisko wykonawcze nie może renderować żadnych treści w żadnym kontenerze przestrzennym.

Jeśli w aktywnym zbiorze renderowania nie ma kontenerów przestrzennych, aplikacja może wywołać xrEndFrame, o ile nie przesyła żadnych warstw kompozycji.

Pamiętaj, że poszczególne łańcuchy wymiany mogą być przesyłane do wielu kontenerów za pomocą warstw w prawidłowej strukturze, np. warstwa quad renderowana za pomocą pojedynczego łańcucha wymiany przesłanego do wielu kontenerów przestrzennych. Ten przypadek jest obsługiwany tak samo jak inne renderowanie: środowisko wykonawcze musi renderować czworokąt we wszystkich takich kontenerach przestrzennych.

Prawidłowe użycie (pośrednie)

Struktura XrSpatialContainerLayerEXT grupuje standardowe warstwy kompozycji i powiązuje je z określonym kontenerem przestrzennym.

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

Opis członka

  • type to XrStructureType tej struktury.
  • next to NULL lub wskaźnik do następnej struktury w łańcuchu struktur.
  • spatialContainer to XrSpatialContainerEXT identyfikujący kontener docelowy.
  • retainPreviousSubmission to XrBool32 . Jeśli XR_TRUE , środowisko wykonawcze zachowa ostatnią przesłaną klatkę dla tego kontenera przestrzennego.
  • layerCount to liczba warstw kompozycji w tablicy layers.
  • layers to wskaźnik do tablicy wskaźników XrCompositionLayerBaseHeader.

Gdy retainPreviousSubmission ma wartość XR_TRUE, środowisko wykonawcze musi ponownie użyć warstw kompozycji i zawartości obrazu łańcucha wymiany, które zostały zablokowane podczas ostatniego wywołania xrEndFrame, gdy retainPreviousSubmission miało wartość XR_FALSE . Wszelkie późniejsze modyfikacje łańcuchów wymiany używanych przez zachowane warstwy nie mogą być odzwierciedlane w wyrenderowanych danych wyjściowych.

W przypadku warstw przesłanych do pojedynczego kontenera przestrzennego (renderowanie wewnątrz kontenera) środowisko wykonawcze musi przestrzegać określonych już reguł dotyczących kolejności kompozycji warstw. Oznacza to, że warstwy w kontenerach muszą być rysowane w takiej samej kolejności, w jakiej są określone, i tworzone za pomocą algorytmu malarskiego.

„Czyszczenie” kontenera przestrzennego odnosi się do usunięcia całej zawartości z kontenera przestrzennego, co powoduje, że w bieżącej klatce nie jest renderowana żadna zawartość tego kontenera. Środowiska wykonawcze muszą traktować to tak, jakby aplikacja przesyłała przezroczystą czerń (wszystkie bity 0) dla każdego piksela w kontenerze. „Zachowanie” kontenera przestrzennego oznacza, że środowisko wykonawcze nadal wyświetla ostatnio przesłany zestaw warstw dla tego kontenera.

W przypadku każdego kontenera przestrzennego aplikacja może określić, czy przesłać nowe warstwy, zachować poprzednie przesłanie czy wyczyścić kontener przestrzenny:

  • Aby przesłać nowe warstwy, aplikacja podaje niezerową wartość layerCount i prawidłowy wskaźnik layers.
  • Aby wyczyścić kontener przestrzenny, wartość layerCount dla jego wpisu musi wynosić 0, a wartość retainPreviousSubmission musi wynosić XR_FALSE .
  • Aby zachować ostatnie przesłane warstwy i obrazy łańcucha wymiany (zachowywanie), wartość layerCount dla wpisu musi wynosić 0, a retainPreviousSubmission musi wynosić XR_TRUE .

To jawne ustawienie dla każdego kontenera zapewnia, że intencja aplikacji jest wyraźnie komunikowana w każdej klatce.

Jeśli retainPreviousSubmission to XR_TRUE, a layerCount nie jest równe 0, środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE .

Jeśli element XrSpatialContainerCompositionLayerViewConfigurationEXT nie jest połączony z elementem XrCompositionLayerProjection, który jest częścią kontenera przestrzennego, środowisko wykonawcze musi zwrócić błąd XR_ERROR_VALIDATION_FAILURE . Ta struktura dotyczy tylko warstw XrCompositionLayerProjection. Jeśli jest połączona z innymi typami warstw (np. warstwami czworokątnymi lub cylindrycznymi), środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE.

Prawidłowe użycie (pośrednie)

Określanie konfiguracji widoku dla warstw projekcji

Struktura XrSpatialContainerCompositionLayerViewConfigurationEXT służy do określania konfiguracji widoku używanej do renderowania warstwy projekcji kontenera przestrzennego.

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

Opis członka

Podczas przesyłania XrCompositionLayerProjection dla kontenera przestrzennego aplikacja musi określić, która konfiguracja widoku została użyta do renderowania warstwy. Jest to konieczne, ponieważ aplikacja może wybrać dla każdej klatki, czy ma renderować z główną konfiguracją widoku kontenera przestrzennego, czy z sugerowaną przez środowisko wykonawcze konfiguracją widoku z zanikiem (jeśli jest dostępna).

Gdy XrSpatialContainerCompositionLayerViewConfigurationEXT jest połączony, aplikacja musi upewnić się, że XrCompositionLayerProjection :: viewCount jest prawidłową liczbą wyświetleń dla XrViewConfigurationType określonego w połączonej strukturze. viewConfigurationType określony w strukturze łańcuchowej musi być XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType określonym podczas uruchamiania kontenera lub typem konfiguracji widoku zdegradowanego zwróconym przez środowisko wykonawcze w XrSpatialContainerViewStateEXT albo dodatkowymi wartościami włączonymi przez rozszerzenie.

Prawidłowe użycie (pośrednie)

Zachowanie przycinania pikseli

Aplikacje powinny informować środowisko wykonawcze, czy renderują piksele poza granicami kontenera przestrzennego, przez połączenie XrSpatialContainerLayerVolumeClippingEXT podczas przesyłania warstw kompozycji.

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

Opis członka

Ta struktura służy jako wskazówka, czy aplikacja renderuje piksele poza granicami kontenera przestrzennego. Gdy kontener przestrzenny jest w trybie imersji, ta wskazówka nie ma znaczenia, ponieważ granice są nieskończone.

W przypadku ograniczonych kontenerów przestrzennych, które korzystają z samodzielnego renderowania, środowisko wykonawcze musi uwzględniać zarówno granice objętości 3D, jak i granice pikseli 2D. Granice objętości 3D są zwracane przez xrGetSpatialContainerBoundsEXT . Granice pikseli 2D to rzutowanie granic objętości 3D na każdy wyświetlacz systemu.

Środowiska wykonawcze muszą odrzucać piksele z obrazów łańcucha wymiany poza granicami pikseli 2D, ale nie mogą odrzucać pikseli, które znajdują się wewnątrz granic pikseli 2D, ale poza granicami objętości 3D. Możliwe są efekty stereo, w których treści wydają się wykraczać poza granice objętości 3D kontenera lub przed nie. Aplikacje mogą odrzucać piksele poza granicami objętości 3D ograniczonego kontenera przestrzennego, aby zmniejszyć paradoksy głębi, i powinny ustawiać wartość volumeClipping na podstawie sposobu, w jaki to robią. Paradoksy głębi często powodują zmęczenie oczu i dyskomfort użytkownika.

Środowiska wykonawcze mogą używać elementu volumeClipping, aby dostosować sposób wyświetlania określonego kontenera przestrzennego. Jeśli na przykład ustawisz wartość XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT, środowisko wykonawcze może renderować tylne powierzchnie granic woluminu 3D, co spowodowałoby paradoksy głębi, gdyby kontener przestrzenny rysował piksele za granicami woluminu 3D kontenera.

Przyszłe rozszerzenia mogą umożliwiać przycinanie na podstawie granic objętości 3D, jeśli zostaną przesłane informacje o głębokości.

Prawidłowe użycie (pośrednie)

Nowe polecenia

Nowe domy

Nowe stałe typu wyliczeniowego

  • XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME
  • XR_EXT_spatial_container_self_rendering_SPEC_VERSION
  • Rozszerzenie 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
  • Rozszerzenie XrSpatialContainerGraphicsPresentationEXT :

    • XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
  • Rozszerzanie 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

Próbki kodu

// 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));

Historia zmian

  • Wersja 1, 6 sierpnia 2026 r. (Lachlan Ford)

    • Początkowy opis rozszerzenia