XR_ANDROID_light_estimation_cubemap

名称字符串

XR_ANDROID_light_estimation_cubemap

扩展类型

实例扩展程序

已注册的扩展程序编号

722

修订版本

1

批准状态

未批准

扩展程序和版本依赖项

XR_ANDROID_light_estimation

上次修改日期

2025-08-06

IP 状态

没有已知的 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
  • nextNULL 或指向结构链中下一个结构的指针。核心 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 数组,由运行时填充支持的立方体贴图分辨率。

立方体贴图分辨率表示立方体贴图每个面的宽度和高度(以像素为单位)。双调用惯用法 然后,应用可以选择在创建光照估算器句柄时使用 XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution 中的某个受支持的分辨率。应用必须根据所选分辨率和颜色格式,为 XrCubemapLightingDataANDROID 的图像缓冲区成员分配适当的内存量。

有效使用情况(隐式)

  • 必须先启用 XR_ANDROID_light_estimation_cubemap 扩展程序,然后才能调用 xrEnumerateCubemapLightingResolutionsANDROID
  • instance 必须是有效的 XrInstance 句柄
  • resolutionCountOutput 必须是指向 uint32_t 值的指针
  • 如果 resolutionCapacityInput 不为 0,则 resolutions 必须是指向 resolutionCapacityInputuint32_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 数组,由运行时填充支持的立方体贴图颜色格式。

双调用惯用法 然后,应用可以选择在创建光照估算器句柄时使用 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
  • nextNULL 或指向结构链中下一个结构的指针。
  • cubemapResolution 是一个 uint32_t,用于指示要使用的立方体贴图照明的分辨率。
  • colorFormat 是一个 XrCubemapLightingColorFormatANDROID,用于指示要使用的立方体贴图光照数据的颜色格式。
  • reproject 是一个 XrBool32,用于指示是否应将立方体贴图光照重新投影到应用的基础空间。

XrCubemapLightEstimatorCreateInfoANDROID 结构描述了用于创建 XrLightEstimatorANDROID 句柄的信息,该句柄能够提供立方体贴图光照估计值。XrCubemapLightEstimatorCreateInfoANDROIDcubemapResolution 成员必须设置为 xrEnumerateCubemapLightingResolutionsANDROID 返回的分辨率之一。XrCubemapLightEstimatorCreateInfoANDROIDcolorFormat 成员必须设置为 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
  • 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 :: 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)

    • 初始扩展程序说明