XR_EXT_spatial_container_self_rendering

Name String

XR_EXT_spatial_container_self_rendering

Тип расширения

Расширение экземпляра

Зарегистрированный добавочный номер

814

Revision

1

Статус ратификации

Не ратифицировано

Зависимости расширений и версий

XR_EXT_spatial_container

Дата последнего изменения

2026-08-06

Статус IP-адреса

Нет известных претензий в отношении интеллектуальной собственности.

Авторы

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

Обзор

Это расширение определяет "самостоятельный рендеринг" для пространственных контейнеров. Пиксели самостоятельно отрисованного пространственного контейнера генерируются приложением и передаются в среду выполнения с помощью стандартных цепочек буферов и слоев композиции OpenXR. Поскольку пространственные контейнеры не всегда занимают все пиксели экрана, среда выполнения сообщает приложениям рекомендуемое разрешение и конфигурацию просмотра каждого пространственного контейнера, чтобы приложения могли выполнять рендеринг более эффективно.

Это расширение в сочетании с XR_EXT_spatial_container предназначено для того, чтобы предложить расширенный набор возможностей по сравнению с обычным рендерингом слоя композиции ядра OpenXR 1.x. Среды выполнения OpenXR 1.x, поддерживающие графический рендеринг и это расширение, должны задавать для XrSystemSpatialContainerPropertiesEXT :: supportsImmersive значение true, чтобы указать, что они поддерживают иммерсивные пространственные контейнеры.

Жизненный цикл рендеринга пространственного контейнера

Чтобы использовать собственный рендеринг для пространственного контейнера, приложение задает для XrSpatialContainerCreateInfoEXT :: graphicsPresentation значение XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT при вызове xrCreateSpatialContainerEXT . После этого приложение может управлять тем, активно ли рендерится пространственный контейнер, вызывая функции xrBeginSpatialContainerRenderingEXT и xrEndSpatialContainerRenderingEXT. Эти функции заменяют xrBeginSession и xrEndSession . Они не являются операциями для отдельных кадров, такими как xrBeginFrame и xrEndFrame .

Для каждого кадра приложение выполняет следующие действия:

  • Вызовите xrWaitFrame и xrBeginFrame . Эти функции не имеют структур, специфичных для контейнеров, и работают так же, как и в основной спецификации.
  • Получайте позы просмотра, параметры проекции и рекомендации по рендерингу для всех пространственных контейнеров, активно выполняющих рендеринг с помощью xrLocateSpatialContainerViewsEXT . Для каждого пространственного контейнера среда выполнения сообщает, следует ли отображать его слои композиции, и рекомендуемый способ отображения слоев, заполняя XrSpatialContainerViewStateEXT .
  • Отрисовывать пиксели в слоях композиции в обычном режиме. У этих операций нет структур, относящихся к контейнерам.
  • Отправьте слои композиции для всех пространственных контейнеров, которые активно отрисовываются, вызвав xrEndFrame и связав XrSpatialContainerLayerFrameEndInfoEXT .

Удаление дескриптора XrSpatialContainerEXT неявно удаляет его из активного набора рендеринга. Приложение может уничтожить пространственный контейнер, даже если оно успешно вызвало xrBeginSpatialContainerRenderingEXT, не связанный с соответствующим вызовом xrEndSpatialContainerRenderingEXT . Среда выполнения должна вести себя так, как будто xrEndSpatialContainerRenderingEXT неявно вызывается в начале реализации xrDestroySpatialContainerEXT, если она возвращает успешный результат.

Когда приложение получает событие XrEventDataSpatialContainerClosedEXT для контейнера в активном наборе рендеринга, оно должно вызвать xrEndSpatialContainerRenderingEXT и уничтожить дескриптор XrSpatialContainerEXT.

Функция xrBeginSpatialContainerRenderingEXT добавляет пространственный контейнер в активный набор рендеринга для сеанса, позволяя приложению отправлять слои композиции для пространственного контейнера в xrEndFrame .

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

Описание параметров

Приложения обычно вызывают его в ответ на событие visible-changed, когда для XrEventDataSpatialContainerVisibleChangedEXT :: visible задано значение true.

Если пространственный контейнер не был создан с помощью XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT при вызове xrCreateSpatialContainerEXT , среда выполнения должна возвращать XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT .

Если пространственный контейнер уже находится в активном наборе рендеринга, среда выполнения должна возвращать XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT .

Если функция xrBeginSpatialContainerRenderingEXT вызывается в момент, когда приложение не может вызвать xrWaitFrame (например, между xrBeginFrame и xrEndFrame), среда выполнения должна вернуть XR_ERROR_CALL_ORDER_INVALID.

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_container_self_rendering должно быть включено до вызова xrBeginSpatialContainerRenderingEXT.
  • session должен быть действительным дескриптором XrSession.
  • beginInfo должен быть указателем на действительную структуру XrSpatialContainerBeginInfoEXT.

Потокобезопасность

Коды возврата

Выполнено

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Сбой

  • 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

Структура XrSpatialContainerBeginInfoEXT используется для указания параметров начала отрисовки пространственного контейнера.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • spatialContainer – XrSpatialContainerEXT, с которого начинается рендеринг.
  • primaryViewConfigurationType – основной тип XrViewConfigurationType, который будет использоваться для пространственного контейнера.

primaryViewConfigurationType – конфигурация представления, которую приложение намерено использовать при рендеринге. Среда выполнения может преобразовать конфигурацию представления в тип с меньшим количеством представлений для оптимизации (например, если контейнер находится очень далеко и он настолько мал, что стереоэффект незаметен). Среда выполнения возвращает сведения о конфигурации затухающего представления из вызовов xrLocateSpatialContainerViewsEXT .

Допустимое использование (неявное)

Функция xrEndSpatialContainerRenderingEXT удаляет пространственный контейнер из активного набора рендеринга.

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

Описание параметров

Обычно приложения вызывают этот метод в ответ на событие visible-changed, когда для XrEventDataSpatialContainerVisibleChangedEXT :: visible задано значение false.

Если пространственный контейнер не находится в активном наборе рендеринга, среда выполнения должна возвращать XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Если функция xrEndSpatialContainerRenderingEXT вызывается в момент, когда приложение не может вызвать xrWaitFrame (например, в период между вызовами xrBeginFrame и xrEndFrame), среда выполнения должна возвращать XR_ERROR_CALL_ORDER_INVALID.

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_container_self_rendering должно быть включено до вызова xrEndSpatialContainerRenderingEXT.
  • session должен быть действительным дескриптором XrSession.
  • endInfo должен быть указателем на действительную структуру XrSpatialContainerEndInfoEXT.

Потокобезопасность

Коды возврата

Выполнено

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Сбой

  • 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

Структура XrSpatialContainerEndInfoEXT используется для указания параметров завершения рендеринга пространственного контейнера.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • spatialContainer – XrSpatialContainerEXT, для которого нужно завершить рендеринг.

Допустимое использование (неявное)

Определение местоположения представлений с помощью xrLocateSpatialContainerViewsEXT

Функция xrLocateSpatialContainerViewsEXT находит представления для набора пространственных контейнеров.

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

Описание параметров

  • session – это XrSession .
  • locateInfo – указатель на структуру XrSpatialContainerViewsLocateInfoEXT.
  • viewStateCount – количество элементов в массиве viewStates.
  • viewStates – указатель на массив структур XrSpatialContainerViewStateEXT, которые будут заполнены средой выполнения.
  • viewCount – это количество элементов в массиве views.
  • views – указатель на массив структур XrView.

Эта функция заменяет xrLocateViews и позволяет приложению запрашивать представления для нескольких пространственных контейнеров одновременно.

Просмотры для всех пространственных контейнеров возвращаются в одном массиве views. Представления упорядочены по индексу пространственного контейнера в массиве XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos, а затем по индексу представления для этого контейнера.

Например, если приложение предоставляет три пространственных контейнера в XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos :

  • Индекс 0: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO (1 просмотр)
  • Индекс 1: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO (2 просмотра)
  • Индекс 2: XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET (4 просмотра)

Затем среда выполнения должна заполнить массив views семью представлениями:

  • views [0] – представление для контейнера 0.
  • views [1] – изображение для левого глаза в контейнере 1.
  • views [2] – это изображение для правого глаза в контейнере 1.
  • views [3] – изображение для левого глаза в контейнере 2.
  • views [4] – это изображение для правого глаза в контейнере 2.
  • views [5] – вставка для левого глаза в контейнере 2.
  • views [6] – это вставка для правого глаза в контейнере 2.

Если viewCount не равно сумме количества просмотров для каждого типа конфигурации запрошенного просмотра пространственного контейнера, среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE .

Среда выполнения может преобразовать конфигурацию представления в тип с меньшим количеством представлений для оптимизации (например, контейнер находится очень далеко и имеет небольшой размер, поэтому стереоэффект незаметен). Если среда выполнения сокращает конфигурацию представлений, она должна возвращать исходное количество представлений для этого контейнера, заполняя дополнительные представления дубликатами сокращенных. Например, если XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO преобразуется в XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO, то и индекс 0, и индекс 1 будут содержать одно моноизображение. Следовательно, общее количество просмотров, возвращаемых в массиве views, не зависит от того, решила ли среда выполнения удалить какие-либо конфигурации просмотров или нет.

Среда выполнения должна адаптировать каждый возвращенный объект XrView :: fov так, чтобы усеченная пирамида была как можно меньше, но при этом содержала все границы соответствующего пространственного контейнера. Среды выполнения могут возвращать несимметричные поля зрения, например если пространственный контейнер находится под косым углом к полю зрения пользователя или частично закрыт другим объектом. Среды выполнения могут свободно размещать целевую поверхность рендеринга для пространственного контейнера. Из-за особенностей рендеринга нескольких приложений, когда пространственные контейнеры отделены от пользователя, среда выполнения может возвращать значения XrView, не подходящие для рендеринга пикселей. Например, если пространственный контейнер не виден на экране, нет допустимых значений для установки XrView :: fov. В таких случаях среды выполнения должны задавать для XrSpatialContainerViewStateEXT :: shouldSubmitLayers значение false.

Среда выполнения возвращает дополнительную информацию о состоянии рендеринга для каждого пространственного контейнера в массиве viewStates. Если viewStateCount не равно XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount , среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE .

После того как среда выполнения поставит в очередь событие XrEventDataSpatialContainerClosedEXT для пространственного контейнера, эта функция должна возвращать XR_FALSE в XrSpatialContainerViewStateEXT :: shouldSubmitLayers и 0 в XrSpatialContainerViewStateEXT :: viewStateFlags для соответствующего пространственного контейнера.

Для пространственных контейнеров, местоположение которых в реальном мире активно меняется, среда выполнения должна учитывать движение контейнера при заполнении views, чтобы минимизировать артефакты репроекции.

Если функция xrLocateSpatialContainerViewsEXT вызывается для одного или нескольких пространственных контейнеров, которые в данный момент не находятся в активном наборе рендеринга, среда выполнения должна возвращать XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_container_self_rendering должно быть включено до вызова xrLocateSpatialContainerViewsEXT.
  • session должен быть действительным дескриптором XrSession.
  • locateInfo должен быть указателем на действительную структуру XrSpatialContainerViewsLocateInfoEXT.
  • viewStates должен быть указателем на массив структур viewStateCount XrSpatialContainerViewStateEXT.
  • views должен быть указателем на массив структур viewCount XrView.
  • Значение параметра viewStateCount должно быть больше 0.
  • Значение параметра viewCount должно быть больше 0.

Коды возврата

Выполнено

  • XR_SUCCESS
  • XR_SESSION_LOSS_PENDING

Сбой

  • 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

Структура XrSpatialContainerViewsLocateInfoEXT содержит параметры для определения местоположения представлений в наборе пространственных контейнеров.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • displayTime – XrTime, в которой нужно найти просмотры.
  • viewLocateInfoCount – количество записей в массиве viewLocateInfos.
  • viewLocateInfos – указатель на массив структур XrSpatialContainerViewLocateInfoEXT.

Допустимое использование (неявное)

Структура XrSpatialContainerViewLocateInfoEXT содержит параметры для отдельного пространственного контейнера, для которого нужно найти представления.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • viewConfigurationType – это XrViewConfigurationType, который будет использоваться для пространственного контейнера.
  • space – это XrSpace, в котором расположены представления пространственного контейнера.
  • spatialContainer – дескриптор XrSpatialContainerEXT.

Приложение может предоставить любое допустимое значение XrSpace в space, однако рекомендуется предоставить пространство пространственного контейнера для соответствующего значения XrSpatialContainerEXT, указанного в структуре XrSpatialContainerViewLocateInfoEXT.

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_container_self_rendering должно быть включено до использования XrSpatialContainerViewLocateInfoEXT.
  • type должно быть XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT
  • next должно быть NULL или действительным указателем на следующую структуру в цепочке структур.
  • viewConfigurationType должно быть действительным значением XrViewConfigurationType.
  • space должен быть действительным идентификатором XrSpace.
  • spatialContainer должен быть действительным дескриптором XrSpatialContainerEXT.
  • И space, и spatialContainer должны быть созданы, выделены или получены из одного и того же XrSession.

Структура XrSpatialContainerViewStateEXT заполняется вызовами xrLocateSpatialContainerViewsEXT с информацией о пригодности рендеринга для каждого пространственного контейнера.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • viewStateFlags – это битовая маска XrViewStateFlags . Эти флаги имеют то же назначение, что и viewStateFlags в основной структуре XrViewState.
  • viewConfigurationType – это XrViewConfigurationType, который указывает тип конфигурации представления, используемый средой выполнения для пространственного контейнера. Среды выполнения могут понизить его до конфигурации представления с меньшим количеством представлений, чем запрошено.
  • shouldSubmitLayers – это XrBool32, возвращенный средой выполнения. Если XR_FALSE, приложение не должно отправлять композицию для этого пространственного контейнера, поскольку он в данный момент не виден или находится в состоянии, когда рендеринг не требуется.
  • recommendedImageExtent – это структура XrExtent2Di, представляющая рекомендуемое разрешение для пространственного контейнера.

Как и в случае с местоположением представления OpenXR, приложение должно проверить XrSpatialContainerViewStateEXT :: viewStateFlags, чтобы убедиться, что положение и ориентация действительны и отслеживаются, прежде чем использовать данные представления для рендеринга.

Приложение должно проверять shouldSubmitLayers и viewConfigurationType, чтобы не отрисовывать больше, чем рекомендует среда выполнения. Если для параметра shouldSubmitLayers задано значение false, приложение меняет поведение отрисовки следующим образом:

  • Приложение не должно считывать соответствующее значение XrView :: fov .
  • Приложение не должно считывать recommendedImageExtent .
  • Приложение не должно выполнять рендеринг в цепочки буферов и отправлять слои композиции для соответствующего пространственного контейнера.
  • Приложение должно задать для XrSpatialContainerLayerEXT :: retainPreviousSubmission значение true. Если приложение все равно отправляет слои, среда выполнения сама решает, что с ними делать (например, она может их удалить).

recommendedImageExtent предназначен для слоев, которые будут обновляться в зависимости от положения контейнера или области просмотра пользователя. При обновлении слоев с контентом, который зависит от положения пространственного контейнера или области просмотра пользователя (например, обычный 3D-контент), приложение должно выполнять рендеринг в этой меньшей области просмотра, а не в рекомендуемой по умолчанию. При обновлении слоев с контентом, который не зависит от положения пространственного контейнера или представления пользователя (например, статических четырехугольных слоев), приложение может игнорировать эти значения. Для слоев, зависящих от вида, recommendedImageExtent – это рекомендация для приложения от среды выполнения, предназначенная для минимизации наложения и повышения производительности рендеринга. При желании приложение может отправлять изображения в полном разрешении.

Значения XrExtent2Di :: width и XrExtent2Di :: height для recommendedImageExtent всегда должны быть положительными целыми числами, которые меньше или равны значениям XrViewConfigurationView :: recommendedImageRectWidth и XrViewConfigurationView :: recommendedImageRectHeight для XrViewConfigurationView в основной конфигурации представления пространственного контейнера. Приложение не должно повторно создавать цепочку буферов только из-за изменения recommendedImageExtent, поскольку это динамическая подсказка для приложения, указывающая, какое значение XrSwapchainSubImage :: imageRect использовать в XrSwapchainSubImage любых отправляемых им слоев композиции с полным разрешением, и оно может меняться в каждом кадре.

Допустимое использование (неявное)

Посмотреть справочное пространство

Опорное пространство вида остается неизменным, как и в ядре OpenXR. Как и в случае с ядром, он не предназначен для рендеринга.

Отправка слоев через xrEndFrame

Чтобы отрисовать пространственные контейнеры, приложение должно предоставить список слоев, связанных с соответствующими пространственными контейнерами, в xrEndFrame . Это делается с помощью структуры XrSpatialContainerLayerFrameEndInfoEXT.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • containerLayerCount – количество элементов в массиве containerLayers.
  • containerLayers – указатель на массив структур XrSpatialContainerLayerEXT.

Массив containerLayers содержит XrSpatialContainerLayerEXT для каждого пространственного контейнера в активном наборе рендеринга (контейнеры, управляемые за сеанс с помощью xrBeginSpatialContainerRenderingEXT и xrEndSpatialContainerRenderingEXT). Каждый XrSpatialContainerLayerEXT содержит список указателей XrCompositionLayerBaseHeader, связанных с данным пространственным контейнером. Среды выполнения могут объединять контейнеры в любом порядке, независимо от порядка containerLayers . Например, среды выполнения могут объединять контейнеры в зависимости от их глубины относительно пользователя, использовать пространственный контейнер в качестве фонового слоя или закреплять пространственный контейнер так, чтобы он всегда находился сверху независимо от его глубины. Среды выполнения могут компоновать слои, используя разные стратегии для пространственных контейнеров в ограниченном режиме или режиме погружения. Например, среды выполнения могут предварительно объединять слои композиции каждого ограниченного пространственного контейнера в один стереофонический четырехугольный слой, который объединяется со всеми остальными контейнерами на втором этапе композиции.

XrFrameEndInfo :: displayTime и XrFrameEndInfo :: environmentBlendMode будут применены ко всем пространственным контейнерам, указанным в XrSpatialContainerLayerFrameEndInfoEXT .

Когда эта структура передается в xrEndFrame путем привязки к XrFrameEndInfo , на основе активного набора рендеринга добавляются следующие дополнительные случаи ошибок:

  • Если на пространственный контейнер ссылается более одного элемента containerLayers , среды выполнения должны возвращать XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT .
  • Если на пространственный контейнер в активном наборе рендеринга не ссылается элемент containerLayers , среды выполнения должны возвращать XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .
  • Если пространственный контейнер, на который ссылается containerLayers, не является частью активного набора рендеринга, среды выполнения должны возвращать XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .

Кроме того, если в активном наборе рендеринга есть пространственные контейнеры и эта структура не связана с XrFrameEndInfo , среды выполнения должны возвращать XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .

В любом из перечисленных выше случаев среда выполнения не должна показывать контент ни в одном пространственном контейнере.

Если в активном наборе рендеринга нет пространственных контейнеров, приложение может вызвать xrEndFrame, если оно не отправляет слои композиции.

Обратите внимание, что отдельные цепочки буферов могут быть отправлены в несколько контейнеров через слои в допустимой структуре. Например, четырехугольный слой, отрисованный через одну цепочку буферов, отправляется в несколько пространственных контейнеров. Этот случай обрабатывается так же, как и другие: среда выполнения должна отображать четырехугольник во всех таких пространственных контейнерах.

Допустимое использование (неявное)

  • Расширение XR_EXT_spatial_container_self_rendering должно быть включено до использования XrSpatialContainerLayerFrameEndInfoEXT.
  • type должно быть XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT
  • next должно быть NULL или действительным указателем на следующую структуру в цепочке структур.
  • containerLayers должен быть указателем на массив из containerLayerCount допустимых структур XrSpatialContainerLayerEXT.
  • Значение параметра containerLayerCount должно быть больше 0.

Структура XrSpatialContainerLayerEXT группирует стандартные слои композиции и связывает их с определенным пространственным контейнером.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • spatialContainer – XrSpatialContainerEXT, идентифицирующий целевой контейнер.
  • retainPreviousSubmission – это XrBool32 . Если XR_TRUE , среда выполнения сохранит последний отправленный кадр для этого пространственного контейнера.
  • layerCount – количество слоев композиции в массиве layers.
  • layers – указатель на массив указателей XrCompositionLayerBaseHeader.

Если retainPreviousSubmission – XR_TRUE, среда выполнения должна повторно использовать слои композиции и содержимое изображения цепочки буферов, зафиксированные во время последнего вызова xrEndFrame, когда retainPreviousSubmission было XR_FALSE . Любые последующие изменения цепочек буферов, используемых сохраненными слоями, не должны отражаться в отрисованных выходных данных.

Для слоев, отправленных для отдельного пространственного контейнера (рендеринг внутри контейнера), среда выполнения должна следовать уже указанным правилам упорядочения композиции слоев. Это означает, что слои в контейнерах должны быть нарисованы в том же порядке, в котором они указаны, и составлены с помощью алгоритма художника.

"Очистка" пространственного контейнера означает удаление всего его содержимого, в результате чего в текущем кадре для этого контейнера ничего не отображается. Среды выполнения должны обрабатывать это так же, как если бы приложение отправляло прозрачный черный цвет (все биты равны 0) для каждого пикселя внутри контейнера. "Сохранение" пространственного контейнера означает, что среда выполнения продолжает показывать последний набор слоев, отправленный для этого контейнера.

Для каждого пространственного контейнера приложение может указать, нужно ли отправить новые слои, сохранить предыдущую отправку или очистить пространственный контейнер:

  • Чтобы отправить новые слои, приложение предоставляет ненулевое значение layerCount и действительный указатель layers.
  • Чтобы очистить пространственный контейнер, для его записи layerCount должно быть равно 0, а retainPreviousSubmission должно быть равно XR_FALSE .
  • Чтобы сохранить последние отправленные слои и изображения цепочки буферов, значение layerCount для записи должно быть равно 0, а значение retainPreviousSubmission должно быть равно XR_TRUE .

Такой явный контроль над каждым контейнером гарантирует, что намерение приложения будет четко передано в каждом кадре.

Если retainPreviousSubmission – это XR_TRUE, а layerCount не равно 0, среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE .

Если XrSpatialContainerCompositionLayerViewConfigurationEXT не привязана к XrCompositionLayerProjection, которая является частью пространственного контейнера, среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE . Эта структура применима только к слоям XrCompositionLayerProjection. Если он связан с другими типами слоев (например, четырехугольными или цилиндрическими), среда выполнения должна возвращать XR_ERROR_VALIDATION_FAILURE.

Допустимое использование (неявное)

Как задать конфигурацию просмотра для слоев проекции

Структура XrSpatialContainerCompositionLayerViewConfigurationEXT используется для указания конфигурации представления, которая применяется для отрисовки слоя проекции пространственного контейнера.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • viewConfigurationType – это XrViewConfigurationType, который использовался для отрисовки XrCompositionLayerProjection .

При отправке XrCompositionLayerProjection для пространственного контейнера приложение должно указать, какая конфигурация представления использовалась для отрисовки слоя. Это необходимо, поскольку приложение может выбирать для каждого кадра, выполнять ли рендеринг с основной конфигурацией представления пространственного контейнера или с предложенной средой выполнения конфигурацией представления с ухудшенным качеством (если она есть).

Если XrSpatialContainerCompositionLayerViewConfigurationEXT связан, приложение должно убедиться, что XrCompositionLayerProjection :: viewCount – это допустимое число просмотров для XrViewConfigurationType, указанного в связанной структуре. Значение viewConfigurationType, указанное в цепочке, должно быть значением XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType, указанным при запуске контейнера, или типом конфигурации представления, возвращенным средой выполнения в XrSpatialContainerViewStateEXT, или дополнительными значениями, включенными через расширение.

Допустимое использование (неявное)

Поведение при обрезке пикселей

Приложения должны сообщать среде выполнения, отрисовывают ли они пиксели за пределами пространственного контейнера. Для этого при отправке слоев композиции нужно использовать цепочку XrSpatialContainerLayerVolumeClippingEXT.

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

Описание участника

  • type – это XrStructureType этой структуры.
  • next – это NULL или указатель на следующую структуру в цепочке.
  • volumeClipping – это XrSpatialContainerVolumeClippingEXT, примененный приложением.

Эта структура служит подсказкой, если приложение отображает пиксели за пределами пространственного контейнера. Когда пространственный контейнер находится в режиме погружения, границы бесконечны, поэтому эта подсказка не имеет значения.

Для ограниченных пространственных контейнеров, использующих самостоятельный рендеринг, среда выполнения должна учитывать как границы трехмерного объема, так и границы двухмерных пикселей. Границы 3D-объема возвращаются из xrGetSpatialContainerBoundsEXT . Границы пикселей 2D – это проекция границ объема 3D на каждый дисплей системы.

Среды выполнения должны отбрасывать пиксели из изображений цепочки буферов за пределами границ 2D-пикселей, но не должны отбрасывать пиксели, которые находятся внутри границ 2D-пикселей, но за пределами границ 3D-объема. Возможны стереоэффекты, при которых контент выходит за пределы трехмерного объема контейнера. Приложения могут отбрасывать пиксели за пределами границ 3D-объема ограниченного пространственного контейнера, чтобы уменьшить парадоксы глубины, и должны устанавливать volumeClipping в зависимости от того, как они это делают. Парадоксы глубины часто вызывают утомление глаз и дискомфорт у пользователей.

Среды выполнения могут использовать volumeClipping, чтобы корректировать отображение определенного пространственного контейнера. Например, если задано значение XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT, среда выполнения может отображать задние грани границ трехмерного объема, что приведет к парадоксам глубины, если пространственный контейнер нарисует пиксели за границами трехмерного объема контейнера.

В будущем может появиться возможность обрезки на основе границ трехмерного объема, если будет предоставлена информация о глубине.

Допустимое использование (неявное)

Новые команды

Новые структуры

Новые константы перечисления

  • XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME
  • XR_EXT_spatial_container_self_rendering_SPEC_VERSION
  • Расширение 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
  • Расширение XrSpatialContainerGraphicsPresentationEXT :

    • XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
  • Расширение 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

Примеры кода

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

История версий

  • Версия 1, 6 августа 2026 г. (Lachlan Ford)

    • Описание расширения