XR_ANDROID_light_estimation_cubemap

名稱字串

XR_ANDROID_light_estimation_cubemap

擴充功能類型

執行個體擴充功能

擴充功能註冊編號

722

修訂版本

1

批准狀態

未批准

擴充功能和版本依附元件

XR_ANDROID_light_estimation

上次修改日期

2025-08-06

IP 狀態

未發現任何智慧財產權聲明。

著作人

Google 的 Salar Khan
Google 的 Scott Chung
Google 的 Jared Finder
Google 的 Spencer Quin
Google 的 Levana Chen
Google 的 Nihav Jain
Google 的 Jürgen Sturm

總覽

這項擴充功能是以基本的 XR_ANDROID_light_estimation 擴充功能為基礎。新增支援取得立方體光源估算值,提供實體環境光源的更詳細估算值。

附註

取得光源估算資料的機制與基本擴充功能相同,但建立光源估算器控制代碼時,XrCubemapLightEstimatorCreateInfoANDROID 必須鏈結至 XrLightEstimatorCreateInfoANDROID

檢查系統功能

typedef struct XrSystemCubemapLightEstimationPropertiesANDROID {
    XrStructureType    type;
    void*              next;
    XrBool32           supportsCubemapLightEstimation;
} XrSystemCubemapLightEstimationPropertiesANDROID;

成員說明

  • type 是這個結構的 XrStructureType
  • nextNULL,或是指向結構鏈中下一個結構的指標。核心 OpenXR 或這個擴充功能中未定義這類結構。
  • supportsCubemapLightEstimationXrBool32,表示目前系統是否支援立方體對應光線估算。

應用程式可以在呼叫 xrGetSystemProperties 時,使用 XrSystemCubemapLightEstimationPropertiesANDROID 結構擴充 XrSystemProperties,檢查系統是否支援立方體光源估算。

如果執行階段針對 supportsCubemapLightEstimation 傳回 XR_FALSE,且 XrCubemapLightEstimatorCreateInfoANDROID 已鏈結至 XrLightEstimatorCreateInfoANDROID,執行階段「必須」xrCreateLightEstimatorANDROID 傳回 XR_ERROR_FEATURE_UNSUPPORTED

有效用量 (隱含)

取得支援的立方體貼圖解析度

XrResult xrEnumerateCubemapLightingResolutionsANDROID(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    uint32_t                                    resolutionCapacityInput,
    uint32_t*                                   resolutionCountOutput,
    uint32_t*                                   resolutions);

參數說明

  • instance 是先前建立的 XrInstance
  • systemId 是先前由 xrGetSystem 擷取的 XrSystemId,用於取得支援的立方體貼圖解析度。
  • resolutionCapacityInputuint32_t,表示儲存在 resolutions 陣列中的元素數量上限。
  • resolutionCountOutput 是指向 uint32_t 的指標,由執行階段設定,指出執行階段寫入 resolutions 陣列的元素數量。
  • resolutionsuint32_t 陣列,執行階段會填入支援的立方體對應解析度。

立方體貼圖解析度是指立方體貼圖每個面的寬度和高度 (以像素為單位)。2 次呼叫慣用語:應用程式可以選擇在建立光線估算器控制代碼時,使用 XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution 中支援的其中一種解析度。應用程式必須根據所選解析度和色彩格式,為 XrCubemapLightingDataANDROID 的圖像緩衝區成員分配適當的記憶體量。

有效用量 (隱含)

  • 呼叫 xrEnumerateCubemapLightingResolutionsANDROID 前,XR_ANDROID_light_estimation_cubemap 擴充功能必須啟用
  • instance 必須是有效的 XrInstance 控制代碼
  • resolutionCountOutput 必須是指向 uint32_t 值的指標
  • 如果 resolutionCapacityInput 不是 0resolutions 必須是指向 resolutionCapacityInput uint32_t 值陣列的指標

傳回代碼

成功

  • XR_SUCCESS

失敗

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_SYSTEM_INVALID
  • XR_ERROR_VALIDATION_FAILURE

取得支援的立方體貼圖顏色格式

XrCubemapLightingColorFormatANDROID 列舉會向執行階段指出要使用的立方體貼圖光源顏色格式。

typedef enum XrCubemapLightingColorFormatANDROID {
    XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID = 1,
    XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID = 2,
    XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID = 3,
    XR_CUBEMAP_LIGHTING_COLOR_FORMAT_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrCubemapLightingColorFormatANDROID;

列舉的意義如下:

列舉說明

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID

具有 3 個管道的色彩格式,每個管道都是 32 位元浮點值。

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

具有 4 個管道的色彩格式,每個管道都是 32 位元浮點值。

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

具有 4 個管道的色彩格式,每個管道都是 16 位元浮點值。

XrResult xrEnumerateCubemapLightingColorFormatsANDROID(
    XrInstance                                  instance,
    XrSystemId                                  systemId,
    uint32_t                                    colorFormatCapacityInput,
    uint32_t*                                   colorFormatCountOutput,
    XrCubemapLightingColorFormatANDROID*        colorFormats);

參數說明

  • instance 是先前建立的 XrInstance
  • systemId 是先前由 xrGetSystem 擷取的 XrSystemId,用於取得支援的立方體貼圖解析度。
  • colorFormatCapacityInputuint32_t,表示儲存在 colorFormats 陣列中的元素數量上限。
  • colorFormatCountOutput 是指向 uint32_t 的指標,由執行階段設定,指出執行階段寫入 colorFormats 陣列的元素數量。
  • colorFormatsXrCubemapLightingColorFormatANDROID 的陣列,由執行階段填入支援的立方體對應顏色格式。

2 次呼叫慣用語:應用程式可以選擇在建立光線估算器控制代碼時,使用 XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat 中支援的其中一種顏色格式。應用程式必須根據所選顏色格式,為 XrCubemapLightingDataANDROID 的圖像緩衝區成員分配適當的記憶體量。

有效用量 (隱含)

傳回代碼

成功

  • XR_SUCCESS

失敗

  • XR_ERROR_FUNCTION_UNSUPPORTED
  • XR_ERROR_HANDLE_INVALID
  • XR_ERROR_INSTANCE_LOST
  • XR_ERROR_RUNTIME_FAILURE
  • XR_ERROR_SIZE_INSUFFICIENT
  • XR_ERROR_SYSTEM_INVALID
  • XR_ERROR_VALIDATION_FAILURE

建立 cubemap 燈光估算器控制代碼

typedef struct XrCubemapLightEstimatorCreateInfoANDROID {
    XrStructureType                        type;
    const void*                            next;
    uint32_t                               cubemapResolution;
    XrCubemapLightingColorFormatANDROID    colorFormat;
    XrBool32                               reproject;
} XrCubemapLightEstimatorCreateInfoANDROID;

成員說明

  • type 是這個結構的 XrStructureType
  • nextNULL,或是指向結構鏈中下一個結構的指標。
  • cubemapResolutionuint32_t,表示要使用的立方體對應照明解析度。
  • colorFormatXrCubemapLightingColorFormatANDROID,表示要使用的立方體對應光源資料顏色格式。
  • reprojectXrBool32,指出是否將立方體對應光照重新投影至應用程式基礎空間。

XrCubemapLightEstimatorCreateInfoANDROID 結構會說明建立 XrLightEstimatorANDROID 控制代碼的資訊,以便提供立方體光源估算值。XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution 成員必須設為 xrEnumerateCubemapLightingResolutionsANDROID 傳回的其中一個解析度。XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat 成員必須設為 xrEnumerateCubemapLightingColorFormatsANDROID 傳回的其中一種顏色格式。如果應用程式未將解析度設為支援的解析度,或將色彩格式設為支援的色彩格式,執行階段必須xrCreateLightEstimatorANDROID 傳回 XR_ERROR_FEATURE_UNSUPPORTED

有效用量 (隱含)

立方體光源估算

typedef struct XrCubemapLightingDataANDROID {
    XrStructureType                type;
    void*                          next;
    XrLightEstimateStateANDROID    state;
    uint32_t                       imageBufferSize;
    uint8_t*                       imageBufferRight;
    uint8_t*                       imageBufferLeft;
    uint8_t*                       imageBufferTop;
    uint8_t*                       imageBufferBottom;
    uint8_t*                       imageBufferFront;
    uint8_t*                       imageBufferBack;
    XrQuaternionf                  rotation;
    XrTime                         centerExposureTime;
} XrCubemapLightingDataANDROID;

成員說明

  • type 是這個結構的 XrStructureType
  • nextNULL,或是指向結構鏈中下一個結構的指標。有效結構包括 XrAmbientLightANDROIDXrSphericalHarmonicsANDROIDXrDirectionalLightANDROID
  • state 是代表光線估算狀態的 XrLightEstimateStateANDROID
  • imageBufferSizeuint32_t,表示立方體對應中每個面部圖像緩衝區的位元組大小。
  • imageBufferRightuint8_t 緩衝區,內含立方體對應的右側臉部圖像。
  • imageBufferLeftuint8_t 緩衝區,內含立方體對應的左側臉部圖像。
  • imageBufferTopuint8_t 緩衝區,內含立方體對應的頂面圖片。
  • imageBufferBottomuint8_t 緩衝區,內含立方體對應的底部影像。
  • imageBufferFrontuint8_t 緩衝區,內含立方體對應的前面影像。
  • imageBufferBackuint8_t 緩衝區,內含立方體對應的背面圖像。
  • rotationXrQuaternionf,表示立方體對應的旋轉。
  • centerExposureTimeXrTime,代表擷取立方體對應的時間。

這個結構可以鏈結至 XrLightEstimateANDROID。如果使用 XrCubemapLightEstimatorCreateInfoANDROID 建立光源估算器控制代碼,執行階段必須只在 xrGetLightEstimateANDROID 中填入這個結構。應用程式必須為圖像緩衝區分配適當的記憶體量,這取決於建立光線估算器控制代碼時,在 XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolutionXrCubemapLightEstimatorCreateInfoANDROID :: colorFormat 中設定的值。應用程式必須XrCubemapLightingDataANDROID :: imageBufferSize 設為每個面部圖像緩衝區的容量 (以位元組為單位)。如果應用程式未使用立方體光源估算,或 XrCubemapLightingDataANDROID :: imageBufferSize 不夠大,無法供執行階段填入圖像緩衝區,執行階段「必須」XrCubemapLightingDataANDROID :: state 設為 XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID

如果應用程式在建立光線估算器控制代碼時,將 XrCubemapLightEstimatorCreateInfoANDROID :: reproject 設為 XR_TRUE,則執行階段「必須」XrCubemapLightingDataANDROID :: rotation 設為身分旋轉,並確保內部旋轉的立方體對應重新投影至應用程式基本空間中身分立方體對應的面上。

光源立方體貼圖的版面配置與 OpenGL 立方體貼圖版面配置相同,如下圖所示

XR ANDROID 光源估算立方體對映版面配置

圖 24. 立方體對映版面配置。

有效用量 (隱含)

  • 必須先啟用 XR_ANDROID_light_estimation_cubemap 擴充功能,才能使用 XrCubemapLightingDataANDROID
  • type 必須XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
  • next 必須NULL,或是指向結構體鏈結中下一個結構體的有效指標
  • state 必須是有效的 XrLightEstimateStateANDROID
  • imageBufferRight 必須是指向 imageBufferSize uint8_t 值陣列的指標
  • imageBufferLeft 必須是指向 imageBufferSize uint8_t 值陣列的指標
  • imageBufferTop 必須是指向 imageBufferSize uint8_t 值陣列的指標
  • imageBufferBottom 必須是指向 imageBufferSize uint8_t 值陣列的指標
  • imageBufferFront 必須是指向 imageBufferSize uint8_t 值陣列的指標
  • imageBufferBack 必須是指向 imageBufferSize uint8_t 值陣列的指標
  • imageBufferSize 參數必須大於 0

光線估算範例程式碼

下列程式碼範例說明如何從執行階段取得所有可能的燈光估算量

XrSession session;  // Created at app startup
XrInstance instance; // Created at app startup
XrSpace appSpace;   // Created previously.
XrSystemId systemId; // Retrieved previously by xrGetSystem
PFN_xrCreateLightEstimatorANDROID xrCreateLightEstimatorANDROID; // Created previously.
PFN_xrDestroyLightEstimatorANDROID xrDestroyLightEstimatorANDROID; // Created previously.
PFN_xrGetLightEstimateANDROID xrGetLightEstimateANDROID; // Created previously.
PFN_xrEnumerateCubemapLightingResolutionsANDROID xrEnumerateCubemapLightingResolutionsANDROID; // Created previously.
PFN_xrEnumerateCubemapLightingColorFormatsANDROID xrEnumerateCubemapLightingColorFormatsANDROID; // Created previously.

XrSystemCubemapLightEstimationPropertiesANDROID props = {
  .type = XR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID};
XrSystemProperties base = {.type = XR_TYPE_SYSTEM_PROPERTIES,
                           .next = &props};
CHK_XR(xrGetSystemProperties(instance, systemId, &base));
if (!props.supportsCubemapLightEstimation) {
   // Cubemap light estimation is not supported
}

uint32_t cubemapResolution = 0;
std::vector<uint32_t> supportedCubemapResolutions;
uint32_t resolutionCount;
CHK_XR(xrEnumerateCubemapLightingResolutionsANDROID(
  instance, systemId, 0, &resolutionCount, nullptr));
supportedCubemapResolutions.resize(resolutionCount);
if (resolutionCount == 0) {
  // No cubemap lighting supported
} else {
  CHK_XR(xrEnumerateCubemapLightingResolutionsANDROID(
    instance, systemId, 0, &resolutionCount, supportedCubemapResolutions.data()));
  cubemapResolution = supportedCubemapResolutions[0];
}

uint32_t pixelCount = cubemapResolution * cubemapResolution;

XrCubemapLightingColorFormatANDROID colorFormat;
std::vector<XrCubemapLightingColorFormatANDROID> supportedColorFormats;
uint32_t colorFormatCount;
CHK_XR(xrEnumerateCubemapLightingColorFormatsANDROID(
  instance, systemId, 0, &colorFormatCount, nullptr));
supportedColorFormats.resize(colorFormatCount);
if (colorFormatCount == 0) {
  // No supported color formats for cubemap lighting. Cannot use cubemap
  // light estimation.
} else {
  CHK_XR(xrEnumerateCubemapLightingColorFormatsANDROID(
    instance, systemId, 0, &colorFormatCount, supportedColorFormats.data()));
  colorFormat = supportedColorFormats[0];
}

uint32_t pixelSize = 0;
switch (colorFormat) {
  case XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID:
    pixelSize = 3 * sizeof(float);
    break;
  case XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID:
    pixelSize = 4 * sizeof(float);
    break;
  case XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID:
    pixelSize = 4 * sizeof(uint16_t);
    break;
  default:
    // Should not happen since the color format was validated previously.
    break;
}

uint32_t perFaceImageBufferSize = pixelCount * pixelSize;

XrLightEstimatorANDROID estimator;
XrCubemapLightEstimatorCreateInfoANDROID cubemapCreateInfo = {
    .type = XR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID,
    .cubemapResolution = cubemapResolution,
    .colorFormat = colorFormat,
    .reproject = XR_TRUE
};
XrLightEstimatorCreateInfoANDROID basicCreateInfo = {
    .type = XR_TYPE_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID,
    .next = &cubemapCreateInfo};
CHK_XR(xrCreateLightEstimatorANDROID(session, &basicCreateInfo, &estimator));

std::vector<uint8_t> cubemapBuffer(perFaceImageBufferSize * 6); // 6 faces * perFaceImageBufferSize

// Every frame
XrTime updateTime;  // Time used for the current frame's simulation update.

XrLightEstimateGetInfoANDROID info = {
    .type = XR_TYPE_LIGHT_ESTIMATE_GET_INFO_ANDROID,
    .space = appSpace,
    .time = updateTime,
};

XrCubemapLightingDataANDROID cubemap = {
    .type = XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID,
    .next = nullptr,
    .imageBufferSize = perFaceImageBufferSize,
    .imageBufferRight = cubemapBuffer.data() + 0 * perFaceImageBufferSize,
    .imageBufferLeft = cubemapBuffer.data() + 1 * perFaceImageBufferSize,
    .imageBufferTop = cubemapBuffer.data() + 2 * perFaceImageBufferSize,
    .imageBufferBottom = cubemapBuffer.data() + 3 * perFaceImageBufferSize,
    .imageBufferFront = cubemapBuffer.data() + 4 * perFaceImageBufferSize,
    .imageBufferBack = cubemapBuffer.data() + 5 * perFaceImageBufferSize,
};

XrDirectionalLightANDROID directionalLight = {
    .type = XR_TYPE_DIRECTIONAL_LIGHT_ANDROID,
    .next = &cubemap,
};

XrSphericalHarmonicsANDROID totalSh = {
    .type = XR_TYPE_SPHERICAL_HARMONICS_ANDROID,
    .next = &directionalLight,
    .kind = XR_SPHERICAL_HARMONICS_KIND_TOTAL_ANDROID,
};

XrSphericalHarmonicsANDROID ambientSh = {
    .type = XR_TYPE_SPHERICAL_HARMONICS_ANDROID,
    .next = &totalSh,
    .kind = XR_SPHERICAL_HARMONICS_KIND_AMBIENT_ANDROID,
};

XrAmbientLightANDROID ambientLight = {
    .type = XR_TYPE_AMBIENT_LIGHT_ANDROID,
    .next = &ambientSh,
};

XrLightEstimateANDROID estimate = {
    .type = XR_TYPE_LIGHT_ESTIMATE_ANDROID,
    .next = &ambientLight,
};

XrResult result = xrGetLightEstimateANDROID(estimator, &info, &estimate);
if (result == XR_SUCCESS &&
    estimate.state == XR_LIGHT_ESTIMATE_STATE_VALID_ANDROID) {
  // use cubemap, directionalLight, totalSh, ambientSh, and
  // ambientLight if each struct has a valid state field

  if (cubemap.state == XR_LIGHT_ESTIMATE_STATE_VALID_ANDROID) {
    // use cubemap
    if (cubemapCreateInfo.reproject == XR_TRUE) {
      XrQuaternionf identityQuaternion = {0.0f, 0.0f, 0.0f, 1.0f};
      assert(memcmp(&cubemap.rotation, &identityQuaternion, sizeof(XrQuaternionf)) == 0);
    }
  }
}

// When you want to disable light estimation
CHK_XR(xrDestroyLightEstimatorANDROID(estimator));

新指令

新結構

新列舉

新增列舉常數

  • XR_ANDROID_LIGHT_ESTIMATION_CUBEMAP_EXTENSION_NAME
  • XR_ANDROID_light_estimation_cubemap_SPEC_VERSION
  • 擴充 XrStructureType

    • XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
    • XR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID
    • XR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID

問題

版本記錄

  • 修訂版本 1,2025-12-05 (Salar Khan)

    • 擴充功能初始說明