XR_ANDROID_light_estimation_cubemap

Name String

XR_ANDROID_light_estimation_cubemap

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

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

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

722

Revision

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, указывающее, поддерживает ли текущая система оценку освещенности кубической карты.

Приложение может проверить, поддерживает ли система оценку освещенности кубической карты, расширив XrSystemProperties с помощью структуры XrSystemCubemapLightEstimationPropertiesANDROID при вызове xrGetSystemProperties .

Если среда выполнения возвращает XR_FALSE для supportsCubemapLightEstimation, а XrCubemapLightEstimatorCreateInfoANDROID привязана к XrLightEstimatorCreateInfoANDROID, среда выполнения должна возвращать XR_ERROR_FEATURE_UNSUPPORTED из xrCreateLightEstimatorANDROID .

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

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

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

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

  • instance – это ранее созданный экземпляр XrInstance.
  • systemId – это XrSystemId, полученный ранее с помощью xrGetSystem, для которого нужно получить поддерживаемые разрешения кубической карты.
  • 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 должен быть указателем на массив значений 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

Формат цвета с тремя каналами, в котором каждый канал представляет собой 32-битное значение с плавающей запятой.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

Формат цвета с четырьмя каналами, каждый из которых представляет собой 32-битное значение с плавающей запятой.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

Формат цвета с четырьмя каналами, каждый из которых представляет собой 16-битное значение с плавающей запятой.

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

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

  • instance – это ранее созданный экземпляр XrInstance.
  • systemId – это XrSystemId, полученный ранее с помощью xrGetSystem, для которого нужно получить поддерживаемые разрешения кубической карты.
  • colorFormatCapacityInput – это uint32_t, указывающий максимальное количество элементов, которые могут храниться в массиве colorFormats.
  • colorFormatCountOutput – указатель на uint32_t, заданный средой выполнения и указывающий количество элементов, записанных в массив colorFormats средой выполнения.
  • colorFormats – массив XrCubemapLightingColorFormatANDROID, который заполняется средой выполнения поддерживаемыми цветовыми форматами кубической карты.

Идиома с двумя вызовами. Затем приложение может выбрать один из поддерживаемых цветовых форматов в XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat при создании дескриптора оценщика освещения. Приложение должно выделить подходящий объем памяти для элементов буфера изображений XrCubemapLightingDataANDROID в зависимости от выбранного формата цвета.

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

  • Расширение XR_ANDROID_light_estimation_cubemap должно быть включено до вызова xrEnumerateCubemapLightingColorFormatsANDROID.
  • instance должен быть действительным дескриптором XrInstance.
  • colorFormatCountOutput должен быть указателем на значение uint32_t.
  • Если colorFormatCapacityInput не равно 0 , colorFormats должен быть указателем на массив значений colorFormatCapacityInput XrCubemapLightingColorFormatANDROID.

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

Выполнено

  • 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 . Элемент colorFormat структуры XrCubemapLightEstimatorCreateInfoANDROID должен быть задан в одном из цветовых форматов, возвращаемых функцией xrEnumerateCubemapLightingColorFormatsANDROID . Если приложение не устанавливает разрешение или формат цвета, которые поддерживаются, среда выполнения должна возвращать XR_ERROR_FEATURE_UNSUPPORTED из xrCreateLightEstimatorANDROID .

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

Оценка освещенности кубической карты

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 . Среда выполнения должна заполнять эту структуру в xrGetLightEstimateANDROID, только если для создания дескриптора оценки освещенности использовалась структура XrCubemapLightEstimatorCreateInfoANDROID. Приложение должно выделить соответствующий объем памяти для буферов изображений, который зависит от значений, заданных в 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, 5 декабря 2025 г. (Салар Хан)

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