XR_EXT_spatial_container_self_rendering

이름 문자열

XR_EXT_spatial_container_self_rendering

확장 프로그램 유형

인스턴스 확장 프로그램

등록된 내선 번호

814

버전

1

승인 상태

비준되지 않음

확장 프로그램 및 버전 종속 항목

XR_EXT_spatial_container

최종 수정일

2026-08-06

IP 상태

알려진 IP 소유권 주장이 없습니다.

도움을 주신 분들

라클란 포드, Google
안드레아스 로브 셀빅, Meta Platforms
아담 구세티스, Meta Platforms
비요른 스웬슨, LÖVR
캐스 에버릿, Meta Platforms
크리스티안 크루즈, Meta Platforms
데니 뢴그렌, Varjo Technologies
프레디아 후야-쿠아디오, Godot Engine
야콥 보르네크란츠, NVIDIA
자레드 파인더, Google
조나단 라이트, Meta Platforms
지안 장, ByteDance
커티스 이블리, Qualcomm
마우리시오 나르바에즈, Meta Platforms
닉 클링겐스미스, Qualcomm
니키타 루트센코, Meta Platforms
프라빈 바부 J D, ByteDance
라일리 파블릭, Collabora
살라 칸, Google
슈아이 리우, ByteDance
월터 루, Meta Platforms
인 리, Microsoft

개요

이 확장 프로그램은 공간 컨테이너의 '자체 렌더링'을 정의합니다. 자체 렌더링된 공간 컨테이너의 픽셀은 모두 앱에서 생성되며 표준 OpenXR 스왑체인 및 컴포지션 레이어를 사용하여 런타임에 제출됩니다. 공간 컨테이너가 항상 화면의 모든 픽셀을 차지하는 것은 아니므로 런타임은 앱이 더 효율적으로 렌더링할 수 있도록 각 공간 컨테이너의 권장 해상도와 뷰 구성을 앱에 알립니다.

이 확장 프로그램은 XR_EXT_spatial_container와 결합되어 기존 OpenXR 1.x 핵심 컴포지션 레이어 렌더링 기능의 상위 집합을 제공합니다. 그래픽 렌더링과 이 확장 프로그램을 지원하는 OpenXR 1.x 런타임은 XrSystemSpatialContainerPropertiesEXT :: supportsImmersive를 true로 설정하여 몰입형 공간 컨테이너를 지원함을 나타내야 합니다(must).

공간 컨테이너 렌더링 수명 주기

공간 컨테이너에 자체 렌더링을 사용하려면 앱이 xrCreateSpatialContainerEXT를 호출할 때 XrSpatialContainerCreateInfoEXT :: graphicsPresentation를 XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT로 설정합니다. 그러면 해당 앱은 xrBeginSpatialContainerRenderingEXT 및 xrEndSpatialContainerRenderingEXT 함수를 호출하여 공간 컨테이너가 활발하게 렌더링되는지 여부를 관리할 수 있습니다. 이러한 함수는 xrBeginSession 및 xrEndSession을 대체합니다. xrBeginFrame 및 xrEndFrame과 같은 프레임별 작업이 아닙니다.

앱은 프레임마다 다음 단계를 거칩니다.

  • xrWaitFrame 및 xrBeginFrame을 호출합니다. 이러한 함수에는 컨테이너별 구조가 없으며 핵심 사양에서와 같이 작동합니다.
  • xrLocateSpatialContainerViewsEXT를 사용하여 활성 상태로 렌더링하는 모든 공간 컨테이너의 뷰 포즈, 프로젝션 매개변수, 렌더링 권장사항을 가져옵니다. 각 공간 컨테이너에 대해 런타임은 XrSpatialContainerViewStateEXT를 작성하여 구성 레이어를 렌더링해야 하는지 여부와 레이어를 렌더링하는 권장 방법을 보고합니다.
  • 픽셀을 컴포지션 레이어로 정상적으로 렌더링합니다. 이러한 작업에는 컨테이너별 구조가 없습니다.
  • xrEndFrame을 호출하고 XrSpatialContainerLayerFrameEndInfoEXT를 연결하여 활성 상태로 렌더링하는 모든 공간 컨테이너의 컴포지션 레이어를 제출합니다.

XrSpatialContainerEXT 핸들을 소멸하면 활성 렌더링 세트에서 암시적으로 삭제됩니다. 앱은 xrEndSpatialContainerRenderingEXT에 대한 상응하는 호출과 연결되지 않은 xrBeginSpatialContainerRenderingEXT를 성공적으로 호출한 경우에도 공간 컨테이너를 소멸시킬 수 있습니다(may). 런타임은 xrDestroySpatialContainerEXT 구현 초기에 필요한 경우 xrEndSpatialContainerRenderingEXT가 암시적으로 호출된 것처럼 동작해야 합니다(성공적으로 반환되는 경우).

앱이 활성 렌더링 세트의 컨테이너에 대한 XrEventDataSpatialContainerClosedEXT 이벤트를 수신하면 해당 앱은 xrEndSpatialContainerRenderingEXT를 호출하고 XrSpatialContainerEXT 핸들을 폐기해야 합니다(should).

xrBeginSpatialContainerRenderingEXT 함수는 공간 컨테이너를 세션별 활성 렌더링 세트에 추가하여 앱이 공간 컨테이너의 컴포지션 레이어를 xrEndFrame에 제출할 수 있도록 합니다.

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

파라미터 설명

앱은 일반적으로 XrEventDataSpatialContainerVisibleChangedEXT :: visible가 true로 설정된 표시 변경 이벤트에 대한 응답으로 이를 호출합니다.

xrCreateSpatialContainerEXT를 호출할 때 공간 컨테이너가 XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT로 생성되지 않은 경우 런타임은 XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT를 반환해야 합니다(must).

공간 컨테이너가 이미 활성 렌더링 세트에 있는 경우 런타임은 XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT를 반환해야 합니다(must).

앱이 xrWaitFrame을 호출할 수 없는 시점(즉, xrBeginFrame 및 xrEndFrame 창 내부)에 xrBeginSpatialContainerRenderingEXT가 호출되면 런타임은 XR_ERROR_CALL_ORDER_INVALID를 반환해야 합니다(must).

올바른 사용 (암시적)

스레드 안전

반품 코드

성공

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

파라미터 설명

앱은 일반적으로 XrEventDataSpatialContainerVisibleChangedEXT :: visible가 false로 설정된 표시 변경 이벤트에 대한 응답으로 이 함수를 호출합니다.

공간 컨테이너가 활성 렌더링 세트에 없으면 런타임은 XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT를 반환해야 합니다(must).

앱이 xrWaitFrame을 호출할 수 없는 시점(즉, xrBeginFrame과 xrEndFrame 호출 사이의 기간)에 xrEndSpatialContainerRenderingEXT가 호출되면 런타임은 XR_ERROR_CALL_ORDER_INVALID를 반환해야 합니다(must).

올바른 사용 (암시적)

스레드 안전

반품 코드

성공

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

파라미터 설명

이 함수는 xrLocateViews를 대체하여 앱이 여러 공간 컨테이너의 뷰를 동시에 쿼리할 수 있도록 합니다.

모든 공간 컨테이너의 뷰는 단일 views 배열로 반환됩니다. 뷰는 XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos 배열의 공간 컨테이너 색인을 기준으로 정렬된 다음 해당 컨테이너의 뷰 색인을 기준으로 정렬됩니다.

예를 들어 앱이 XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos에서 공간 컨테이너 3개를 제공하는 경우 다음과 같습니다.

  • 색인 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 배열을 7개의 뷰로 채워야 합니다.

  • 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를 반환해야 합니다(MUST).

런타임은 최적화를 위해 뷰 구성이 뷰가 더 적은 유형으로 저하될 수 있습니다(예: 컨테이너가 매우 멀리 있고 작아서 스테레오를 인식할 수 없음). 런타임이 뷰 구성을 감소시키는 경우 런타임은 여전히 해당 컨테이너의 원래 뷰 수를 반환해야 하며, 감소된 뷰의 중복으로 추가 뷰를 채워야 합니다. 예를 들어 XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO가 XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO로 감소하면 색인 0과 색인 1 모두에 단일 모노 뷰가 포함됩니다. 따라서 views 배열에 반환되는 총 뷰 수는 런타임에서 뷰 구성을 감쇠하기로 결정했는지 여부와 관계가 없습니다.

런타임은 반환된 각 XrView :: fov를 조정하여 절두체가 가능한 한 작으면서도 해당 공간 컨테이너의 전체 경계를 포함하도록 해야 합니다. 런타임은 비대칭 FOV를 반환할 수 있습니다. 예를 들어 공간 컨테이너가 사용자의 시야에 대해 비스듬한 각도에 있거나 다른 객체에 의해 부분적으로 가려진 경우입니다. 런타임은 공간 컨테이너의 타겟 렌더링 노출 영역을 자유롭게 배치할 수 있습니다(may). 공간 컨테이너가 사용자로부터 분리되는 멀티 앱 렌더링의 특성으로 인해 런타임은 픽셀 렌더링에 적합하지 않은 XrView 값을 반환할 수 있습니다. 예를 들어 공간 컨테이너가 화면에 표시되지 않으면 XrView :: fov를 설정할 유효한 값이 없습니다. 이러한 경우 런타임은 XrSpatialContainerViewStateEXT :: shouldSubmitLayers를 false로 설정해야 합니다.

런타임은 viewStates 배열에 공간 컨테이너별 추가 렌더링 상태 정보를 반환합니다. viewStateCount가 XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount와 같지 않으면 런타임은 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must).

런타임이 공간 컨테이너의 XrEventDataSpatialContainerClosedEXT 이벤트를 큐에 추가한 후 이 함수는 해당 공간 컨테이너의 XrSpatialContainerViewStateEXT :: shouldSubmitLayers에서 XR_FALSE를, XrSpatialContainerViewStateEXT :: viewStateFlags에서 0을 반환해야 합니다.

실제 세계에서 위치가 활발하게 변경되는 공간 컨테이너의 경우 런타임은 재투영 아티팩트를 최소화하기 위해 views를 채울 때 컨테이너의 움직임을 고려해야 합니다(SHOULD).

현재 활성 렌더링 세트에 없는 하나 이상의 공간 컨테이너에 대해 xrLocateSpatialContainerViewsEXT가 호출되면 런타임은 XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT를 반환해야 합니다(must).

올바른 사용 (암시적)

  • XR_EXT_spatial_container_self_rendering 확장 프로그램은 xrLocateSpatialContainerViewsEXT를 호출하기 전에 사용 설정해야 합니다.
  • session는 유효한 XrSession 핸들이어야 합니다.
  • locateInfo는 유효한 XrSpatialContainerViewsLocateInfoEXT 구조에 대한 포인터여야 합니다.
  • viewStates는 viewStateCount XrSpatialContainerViewStateEXT 구조의 배열에 대한 포인터여야 합니다(must).
  • 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 구조의 배열에 대한 포인터입니다.

올바른 사용 (암시적)

  • XR_EXT_spatial_container_self_rendering 확장 프로그램은 XrSpatialContainerViewsLocateInfoEXT를 사용하기 전에 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • viewLocateInfos은 유효한 XrSpatialContainerViewLocateInfoEXT 구조 viewLocateInfoCount개의 배열에 대한 포인터여야 합니다.
  • viewLocateInfoCount 매개변수는 0보다 커야 합니다.

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 핸들입니다.

앱은 space에서 유효한 XrSpace를 제공할 수 있지만 XrSpatialContainerViewLocateInfoEXT 구조 내에 지정된 해당 XrSpatialContainerEXT의 공간 컨테이너 공간을 제공하는 것이 좋습니다.

올바른 사용 (암시적)

  • XR_EXT_spatial_container_self_rendering 확장 프로그램은 XrSpatialContainerViewLocateInfoEXT를 사용하기 전에 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • viewConfigurationType: 유효한 XrViewConfigurationType 값이어야 합니다.
  • space는 유효한 XrSpace 핸들이어야 합니다(must).
  • 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의 비트 마스크입니다. 이러한 플래그는 핵심 XrViewState 구조의 viewStateFlags와 동일한 용도로 사용됩니다.
  • viewConfigurationType은 런타임이 공간 컨테이너에 사용하는 뷰 구성 유형을 나타내는 XrViewConfigurationType입니다. 런타임은 요청된 것보다 뷰 수가 적은 뷰 구성으로 감소할 수 있습니다.
  • shouldSubmitLayers는 런타임에서 반환하는 XrBool32입니다. XR_FALSE인 경우 앱은 현재 표시되지 않거나 렌더링이 필요하지 않은 상태이므로 이 공간 컨테이너의 컴포지션을 제출하지 않아야 합니다(should).
  • recommendedImageExtent는 공간 컨테이너의 권장 해상도를 나타내는 XrExtent2Di 구조입니다.

핵심 OpenXR 뷰 위치와 마찬가지로 앱은 XrSpatialContainerViewStateEXT :: viewStateFlags를 확인하여 렌더링에 뷰 데이터를 사용하기 전에 위치와 방향이 유효하고 추적되는지 확인해야 합니다.

앱은 런타임에서 권장하는 것보다 더 많이 렌더링하지 않도록 shouldSubmitLayers 및 viewConfigurationType를 확인해야 합니다(SHOULD). shouldSubmitLayers가 false이면 앱은 다음과 같이 렌더링 동작을 변경합니다.

  • 앱은 해당 XrView :: fov를 읽으면 안 됩니다(must). .
  • 앱은 recommendedImageExtent를 읽지 않아야 합니다.
  • 앱은 스왑체인에 렌더링하고 해당 공간 컨테이너의 컴포지션 레이어를 제출하지 않아야 합니다.
  • 앱은 XrSpatialContainerLayerEXT :: retainPreviousSubmission를 true로 설정해야 합니다(should). 앱이 레이어를 제출하기로 선택한 경우 레이어에 관한 처리 방식은 런타임에 따라 결정됩니다 (예: 런타임은 레이어를 삭제하기로 선택할 수 있음).

recommendedImageExtent은 컨테이너 위치 또는 사용자 뷰에 따라 업데이트되는 레이어에 명시적으로 사용됩니다. 공간 컨테이너의 위치 또는 사용자의 뷰에 따라 달라지는 콘텐츠(예: 일반 3D 콘텐츠)로 레이어를 업데이트할 때 앱은 기본 권장 뷰 크기 대신 이 더 작은 표시 영역으로 렌더링해야 합니다(should). 공간 컨테이너의 위치나 사용자의 뷰에 의존하지 않는 콘텐츠 (예: 정적 쿼드 레이어)로 레이어를 업데이트할 때 앱은 이러한 값을 안전하게 무시할 수 있습니다. 뷰 종속 레이어의 경우 recommendedImageExtent은 앨리어싱을 최소화하고 렌더링 성능을 개선하기 위해 런타임에서 앱에 권장하는 값입니다. 앱은 원하는 경우 전체 해상도로 제출할 수 있습니다.

recommendedImageExtent의 XrExtent2Di :: width 및 XrExtent2Di :: height는 항상 공간 컨테이너의 기본 뷰 구성에 관한 XrViewConfigurationView :: recommendedImageRectWidth 및 XrViewConfigurationView :: recommendedImageRectHeight의 XrViewConfigurationView보다 작거나 같은 양의 정수여야 합니다. 앱은 recommendedImageExtent가 변경되었다는 이유만으로 스왑체인을 다시 만들면 안 됩니다(SHOULD NOT). 이는 앱이 제출하는 전체 해상도 컴포지션 레이어의 XrSwapchainSubImage에서 사용할 XrSwapchainSubImage :: imageRect를 지정하는 동적 힌트이며 프레임마다 변경될 수 있기(CAN) 때문입니다.

올바른 사용 (암시적)

  • XrSpatialContainerViewStateEXT를 사용하기 전에 XR_EXT_spatial_container_self_rendering 확장 프로그램을 사용 설정해야 합니다.
  • type은(는) XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT여야 합니다.
  • next는 NULL 또는 구조 체인의 다음 구조에 대한 유효한 포인터여야 합니다.
  • viewStateFlags는 XrViewStateFlagBits 값의 유효한 조합이어야 합니다(must).
  • viewStateFlags은(는) 0이면 안 됩니다.
  • viewConfigurationType: 유효한 XrViewConfigurationType 값이어야 합니다.

참조 공간 보기

뷰 참조 공간은 OpenXR 코어에 있는 그대로 변경되지 않습니다. 핵심과 마찬가지로 렌더링에 사용하기 위한 것이 아닙니다.

xrEndFrame을 통해 레이어 제출

공간 컨테이너를 렌더링하려면 앱이 각 공간 컨테이너와 연결된 레이어 목록을 xrEndFrame에 제공해야 합니다(must). 이는 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의 순서와 관계없이 선택한 순서대로 컨테이너를 구성할 수 있습니다(may). 예를 들어 런타임은 사용자와의 상대적 깊이에 따라 컨테이너를 합성하거나, 공간 컨테이너를 배경 레이어로 사용하거나, 깊이에 관계없이 항상 맨 위에 있도록 공간 컨테이너를 '고정'할 수 있습니다. 런타임은 경계 모드 또는 몰입형 모드에서 공간 컨테이너에 다양한 전략을 사용하여 레이어를 합성할 수 있습니다(may). 예를 들어 런타임은 각 경계 공간 컨테이너의 컴포지션 레이어를 두 번째 컴포지션 단계에서 다른 모든 컨테이너와 결합된 단일 스테레오 쿼드 레이어로 사전 구성할 수 있습니다(may).

XrFrameEndInfo :: displayTime 및 XrFrameEndInfo :: environmentBlendMode는 XrSpatialContainerLayerFrameEndInfoEXT에 제공된 모든 공간 컨테이너에 적용됩니다.

이 구조가 XrFrameEndInfo에 연결되어 xrEndFrame에 전달되면 활성 렌더링 세트에 따라 다음과 같은 추가 오류 사례가 추가됩니다.

  • 공간 컨테이너가 containerLayers의 요소 두 개 이상에서 참조되는 경우 런타임은 XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT를 반환해야 합니다(MUST).
  • 활성 렌더링 세트의 공간 컨테이너가 containerLayers의 요소에서 참조되지 않는 경우 런타임은 XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT를 반환해야 합니다(must).
  • containerLayers에서 참조하는 공간 컨테이너가 활성 렌더링 세트의 구성원이 아닌 경우 런타임은 XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT를 반환해야 합니다(must).

또한 활성 렌더링 세트에 공간 컨테이너가 있고 이 구조가 XrFrameEndInfo에 연결되어 있지 않으면 런타임은 XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT를 반환해야 합니다(must).

위의 오류 사례 중 하나라도 발생하면 런타임은 공간 컨테이너의 콘텐츠를 렌더링하지 않아야 합니다(must).

활성 렌더링 세트에 공간 컨테이너가 없는 경우 앱은 컴포지션 레이어를 제출하지 않는 한 xrEndFrame을 호출할 수 있습니다.

개별 스왑체인은 유효한 구조의 레이어를 통해 여러 컨테이너에 제출될 수 있습니다(예: 여러 공간 컨테이너에 제출된 단일 스왑체인을 통해 렌더링된 쿼드 레이어). 이 케이스는 다른 렌더링과 동일하게 처리됩니다. 런타임은 이러한 모든 공간 컨테이너에서 쿼드를 렌더링해야 합니다(MUST).

올바른 사용 (암시적)

  • XrSpatialContainerLayerFrameEndInfoEXT를 사용하기 전에 XR_EXT_spatial_container_self_rendering 확장 프로그램을 사용 설정해야 합니다.
  • 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인 경우 런타임은 retainPreviousSubmission가 XR_FALSE인 가장 최근의 xrEndFrame 호출 중에 래치된 컴포지션 레이어와 스왑체인 이미지 콘텐츠를 재사용해야 합니다(MUST). 유지된 레이어에서 사용하는 스왑체인에 대한 후속 수정사항은 렌더링된 출력에 반영되지 않아야 합니다(must).

개별 공간 컨테이너에 제출된 레이어 (컨테이너 내 렌더링)의 경우 런타임은 이미 지정된 레이어 구성 순서 규칙을 따라야 합니다. 즉, 컨테이너 내의 레이어는 지정된 순서대로 그려져야 하며 화가 알고리즘을 통해 구성됩니다.

공간 컨테이너를 '지운다'는 것은 공간 컨테이너에서 모든 콘텐츠를 삭제하여 현재 프레임에서 해당 컨테이너에 아무것도 렌더링되지 않도록 하는 것을 의미합니다. 런타임은 이를 컨테이너 내부의 모든 픽셀에 대해 투명한 검은색(모든 비트 0)을 제출하는 앱과 동일하게 처리해야 합니다(must). 공간 컨테이너를 '유지'한다는 것은 런타임이 해당 컨테이너에 대해 가장 최근에 제출된 레이어 집합을 계속 표시하는 것을 의미합니다.

각 공간 컨테이너에 대해 앱은 새 레이어를 제출할지, 이전 제출을 유지할지, 공간 컨테이너를 지울지 지정할 수 있습니다.

  • 새 레이어를 제출하기 위해 앱은 0이 아닌 layerCount 및 유효한 layers 포인터를 제공합니다.
  • 공간 컨테이너를 지우려면 항목의 layerCount가 0이어야 하고 retainPreviousSubmission는 XR_FALSE여야 합니다.
  • 마지막으로 제출된 레이어와 스왑체인 이미지를 유지하려면 (유지) 항목의 layerCount가 0이어야 하고 retainPreviousSubmission는 XR_TRUE여야 합니다.

이러한 명시적인 컨테이너별 제어를 통해 앱의 의도가 모든 프레임에서 명확하게 전달됩니다.

retainPreviousSubmission가 XR_TRUE이고 layerCount가 0이 아니면 런타임은 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(MUST).

XrSpatialContainerCompositionLayerViewConfigurationEXT가 공간 컨테이너의 일부인 XrCompositionLayerProjection에 연결되지 않은 경우 런타임은 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must). 이 구조는 XrCompositionLayerProjection 레이어에만 적용됩니다. 다른 레이어 유형(예: 쿼드 또는 실린더 레이어)에 연결된 경우 런타임은 XR_ERROR_VALIDATION_FAILURE를 반환해야 합니다(must).

올바른 사용 (암시적)

투사 레이어의 뷰 구성 지정

XrSpatialContainerCompositionLayerViewConfigurationEXT 구조는 공간 컨테이너의 프로젝션 레이어를 렌더링하는 데 사용되는 뷰 구성을 지정하는 데 사용됩니다.

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

회원 설명

공간 컨테이너의 XrCompositionLayerProjection을 제출할 때 앱은 레이어를 렌더링하는 데 사용된 뷰 구성을 지정해야 합니다(must). 이는 앱이 각 프레임에서 공간 컨테이너의 기본 뷰 구성으로 렌더링할지 아니면 런타임에서 제안한 감쇠된 뷰 구성(있는 경우)으로 렌더링할지 선택할 수 있기 때문에 필요합니다.

XrSpatialContainerCompositionLayerViewConfigurationEXT가 연결된 경우 앱은 XrCompositionLayerProjection :: viewCount가 연결된 구조에 지정된 XrViewConfigurationType의 유효한 뷰 수인지 확인해야 합니다. 연결된 구조에 지정된 viewConfigurationType는 컨테이너가 시작될 때 지정된 XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType, XrSpatialContainerViewStateEXT에서 런타임에 의해 반환된 감쇠된 뷰 구성 유형 또는 확장 프로그램을 통해 사용 설정된 추가 값이어야 합니다.

올바른 사용 (암시적)

픽셀 클리핑 동작

앱은 구성 레이어를 제출할 때 XrSpatialContainerLayerVolumeClippingEXT를 연결하여 공간 컨테이너의 경계 외부에 픽셀을 렌더링하는지 여부를 런타임에 알려야 합니다(should).

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

회원 설명

이 구조는 앱이 공간 컨테이너의 경계 외부에 픽셀을 렌더링하는지 여부에 관한 힌트 역할을 합니다. 공간 컨테이너가 몰입형 모드인 경우 경계가 무한하므로 이 힌트는 의미가 없습니다.

자체 렌더링을 사용하는 경계가 있는 공간 컨테이너의 경우 런타임은 3D 볼륨 경계와 2D 픽셀 경계를 모두 추론해야 합니다. 3D 볼륨 경계는 xrGetSpatialContainerBoundsEXT에서 반환됩니다. 2D 픽셀 경계는 시스템의 각 디스플레이에 대한 3D 볼륨 경계의 투영입니다.

런타임은 2D 픽셀 경계 외부의 스왑체인 이미지에서 픽셀을 삭제해야 합니다(MUST). 하지만 런타임은 2D 픽셀 경계 내부에 있지만 3D 볼륨 경계 외부에 있는 픽셀을 삭제하면 안 됩니다(MUST NOT). 콘텐츠가 컨테이너의 3D 볼륨 경계를 넘어 확장되거나 그 앞에 표시되는 스테레오 효과가 가능합니다. 앱은 깊이 역설을 줄이기 위해 경계가 지정된 공간 컨테이너의 3D 볼륨 경계 외부에 있는 픽셀을 삭제할 수 있으며(may) 삭제 방식에 따라 volumeClipping를 설정해야 합니다(should). 깊이 역설은 눈의 피로와 사용자 불편을 유발하는 경우가 많습니다.

런타임은 volumeClipping를 사용하여 특정 공간 컨테이너를 표시하는 방식을 조정할 수 있습니다(may). 예를 들어 XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT로 설정하면 런타임은 공간 컨테이너가 컨테이너의 3D 볼륨 경계 뒤에 픽셀을 그리는 경우 깊이 역설을 일으킬 수 있는 3D 볼륨 경계의 후면을 렌더링할 수 있습니다.

향후 확장 프로그램은 깊이 정보가 제출된 경우 3D 볼륨 경계를 기반으로 클리핑을 허용할 수 있습니다.

올바른 사용 (암시적)

새 명령어

새로운 구조

새 enum 상수

  • 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, 2026년 8월 6일 (라클란 포드)

    • 초기 확장 프로그램 설명