XR_ANDROID_light_estimation_cubemap

Name String

XR_ANDROID_light_estimation_cubemap

擴充功能類型

執行個體擴充功能

擴充功能註冊編號

722

修訂版本

1

批准狀態

未批准

擴充功能和版本依附元件

XR_ANDROID_light_estimation

上次修改日期

2025-08-06

IP 狀態

沒有已知的智慧財產權聲明。

著作人

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

總覽

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

注意事項

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

檢查系統功能

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

成員說明

  • type 是這個結構的 XrStructureType。
  • next 是 NULL,或指向結構鏈中下一個結構的指標。核心 OpenXR 或這個擴充功能中未定義這類結構。
  • supportsCubemapLightEstimation 是 XrBool32,表示目前系統是否支援立方體貼圖光線估測。

應用程式可以檢查系統是否支援立方體光源估算,方法是在呼叫 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,用於取得支援的立方體貼圖解析度。
  • resolutionCapacityInput 是 uint32_t,表示resolutions陣列可儲存的元素數量上限。
  • resolutionCountOutput 是指向 uint32_t 的指標,由執行階段設定,表示執行階段寫入 resolutions 陣列的元素數量。
  • resolutions 是 uint32_t 陣列,由執行階段填入支援的立方體對應解析度。

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

有效用途 (隱含)

  • 必須先啟用 XR_ANDROID_light_estimation_cubemap 擴充功能,才能呼叫 xrEnumerateCubemapLightingResolutionsANDROID
  • instance「必須」是有效的 XrInstance 控制代碼
  • resolutionCountOutput「必須」是指向 uint32_t 值的指標
  • 如果 resolutionCapacityInput 不是 0,resolutions「必須」是指向 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,用於取得支援的立方體貼圖解析度。
  • colorFormatCapacityInput 是 uint32_t,表示colorFormats陣列可儲存的元素數量上限。
  • colorFormatCountOutput 是指向 uint32_t 的指標,由執行階段設定,表示執行階段寫入 colorFormats 陣列的元素數量。
  • colorFormats 是 XrCubemapLightingColorFormatANDROID 陣列,由執行階段填入支援的立方體對應色彩格式。

2-call idiom 應用程式可以選擇在建立光線估算器控制代碼時,使用 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

建立立方體貼圖光線估測器控制代碼

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

成員說明

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

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。
  • next 是 NULL,或指向結構鏈中下一個結構的指標。有效結構包括 XrAmbientLightANDROID、XrSphericalHarmonicsANDROID、XrDirectionalLightANDROID。
  • state 是代表光線估算狀態的 XrLightEstimateStateANDROID。
  • imageBufferSize 是 uint32_t,代表立方體對應中各面圖片緩衝區的位元組大小。
  • imageBufferRight 是 uint8_t 緩衝區,包含立方體對應的右側圖片。
  • imageBufferLeft 是 uint8_t 緩衝區,包含立方體對應的左側臉部圖片。
  • imageBufferTop 是 uint8_t 緩衝區,包含立方體對應的頂面圖片。
  • imageBufferBottom 是 uint8_t 緩衝區,包含立方體對應的底面圖片。
  • imageBufferFront 是 uint8_t 緩衝區,內含立方體對應的正向面圖片。
  • imageBufferBack 是 uint8_t 緩衝區,包含立方體貼圖的背面圖片。
  • rotation 是 XrQuaternionf,代表立方體對應的旋轉。
  • centerExposureTime 是 XrTime,代表擷取立方體對應的時間。

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

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

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

XR ANDROID 光源估成立方體貼圖版面配置

圖 31. 立方體貼圖版面配置。

有效用途 (隱含)

  • 必須先啟用 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)

    • 初始擴充功能說明