XR_ANDROID_light_estimation_cubemap

Cadena de nombre

XR_ANDROID_light_estimation_cubemap

Tipo de extensión

Extensión de la instancia

Número de extensión registrado

722

Revisión

1

Estado de ratificación

No se ratificó

Dependencias de extensiones y versiones

XR_ANDROID_light_estimation

Fecha de la última modificación

2025-08-06

Estado de la IP

No hay reclamos conocidos por IP.

Colaboradores

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

Descripción general

Esta extensión se basa en la extensión básica de XR_ANDROID_light_estimation. Se agregó compatibilidad para obtener estimaciones de iluminación de mapas de cubos, lo que proporciona estimaciones más detalladas sobre la iluminación en el entorno físico.

Nota

El mecanismo para obtener los datos de estimación de luz es el mismo que el de la extensión básica, excepto que XrCubemapLightEstimatorCreateInfoANDROID debe encadenarse a XrLightEstimatorCreateInfoANDROID cuando se crea el identificador del estimador de luz.

Inspecciona la capacidad del sistema

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

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras. No se definen tales estructuras en OpenXR principal ni en esta extensión.
  • supportsCubemapLightEstimation es un XrBool32 que indica si el sistema actual admite la estimación de luz de mapa de cubo.

Una aplicación puede inspeccionar si el sistema es capaz de admitir la estimación de luz de mapa de cubo extendiendo XrSystemProperties con la estructura XrSystemCubemapLightEstimationPropertiesANDROID cuando se llama a xrGetSystemProperties .

Si el tiempo de ejecución devuelve XR_FALSE para supportsCubemapLightEstimation y XrCubemapLightEstimatorCreateInfoANDROID se encadenó a XrLightEstimatorCreateInfoANDROID , el tiempo de ejecución debe devolver XR_ERROR_FEATURE_UNSUPPORTED de xrCreateLightEstimatorANDROID .

Uso válido (implícito)

Cómo obtener resoluciones de mapa de cubo compatibles

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

Descripciones de los parámetros

  • instance es un XrInstance creado anteriormente.
  • systemId es el XrSystemId recuperado anteriormente por xrGetSystem para el que se deben obtener las resoluciones de mapa de cubo admitidas.
  • resolutionCapacityInput es un uint32_t que indica la cantidad máxima de elementos que se pueden almacenar en el array resolutions.
  • resolutionCountOutput es un puntero a un uint32_t que establece el tiempo de ejecución y que indica la cantidad de elementos que el tiempo de ejecución escribió en el array resolutions.
  • resolutions es un array de uint32_t que el entorno de ejecución propaga con las resoluciones de mapa de cubo admitidas.

La resolución de un mapa de cubo indica el ancho y la altura de cada cara del mapa de cubo en píxeles. Modismo de 2 llamadas Luego, la aplicación puede elegir usar una de las resoluciones admitidas en XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution cuando crea el identificador del estimador de luz. La aplicación debe asignar la cantidad adecuada de memoria para los miembros del búfer de imágenes de XrCubemapLightingDataANDROID según la resolución elegida y el formato de color.

Uso válido (implícito)

  • La extensión XR_ANDROID_light_estimation_cubemap debe habilitarse antes de llamar a xrEnumerateCubemapLightingResolutionsANDROID
  • instance debe ser un identificador de XrInstance válido
  • resolutionCountOutput debe ser un puntero a un valor uint32_t.
  • Si resolutionCapacityInput no es 0 , resolutions debe ser un puntero a un array de valores resolutionCapacityInput uint32_t.

Códigos de retorno

Listo

  • XR_SUCCESS

Falla

  • 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

Cómo obtener formatos de color de mapa de cubo admitidos

La enumeración XrCubemapLightingColorFormatANDROID identifica para el tiempo de ejecución el formato de color de la iluminación del mapa de cubos que se debe usar.

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;

Los enums tienen los siguientes significados:

Descripción de la enumeración

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID

Es un formato de color con 3 canales en el que cada canal es un valor de punto flotante de 32 bits.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

Es un formato de color con 4 canales en el que cada canal es un valor de punto flotante de 32 bits.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

Es un formato de color con 4 canales en el que cada canal es un valor de punto flotante de 16 bits.

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

Descripciones de los parámetros

  • instance es un XrInstance creado anteriormente.
  • systemId es el XrSystemId recuperado anteriormente por xrGetSystem para el que se deben obtener las resoluciones de mapa de cubo admitidas.
  • colorFormatCapacityInput es un uint32_t que indica la cantidad máxima de elementos que se pueden almacenar en el array colorFormats.
  • colorFormatCountOutput es un puntero a un uint32_t que establece el tiempo de ejecución y que indica la cantidad de elementos que el tiempo de ejecución escribió en el array colorFormats.
  • colorFormats es un array de XrCubemapLightingColorFormatANDROID que el tiempo de ejecución completa con los formatos de color de mapa de cubo admitidos.

Modismo de 2 llamadas Luego, la aplicación puede elegir usar uno de los formatos de color admitidos en XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat cuando crea el identificador del estimador de luz. La aplicación debe asignar la cantidad adecuada de memoria para los miembros del búfer de imágenes de XrCubemapLightingDataANDROID según el formato de color elegido.

Uso válido (implícito)

Códigos de retorno

Listo

  • XR_SUCCESS

Falla

  • 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

Crea un identificador del estimador de luz de mapa de cubos

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

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras.
  • cubemapResolution es un uint32_t que indica la resolución de la iluminación del mapa de cubo que se usará.
  • colorFormat es un XrCubemapLightingColorFormatANDROID que indica el formato de color de los datos de iluminación del mapa de cubo que se usará.
  • reproject es un XrBool32 que indica si la iluminación del mapa de cubos debe proyectarse de nuevo en el espacio base de la aplicación.

La estructura XrCubemapLightEstimatorCreateInfoANDROID describe la información para crear un identificador XrLightEstimatorANDROID que pueda proporcionar estimaciones de iluminación de mapa de cubo. El miembro cubemapResolution de XrCubemapLightEstimatorCreateInfoANDROID debe establecerse en una de las resoluciones que devuelve xrEnumerateCubemapLightingResolutionsANDROID . El miembro XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat debe establecerse en uno de los formatos de color que devuelve xrEnumerateCubemapLightingColorFormatsANDROID . Si la aplicación no establece la resolución en una de las resoluciones admitidas o el formato de color en uno de los formatos de color admitidos, el tiempo de ejecución debe devolver XR_ERROR_FEATURE_UNSUPPORTED desde xrCreateLightEstimatorANDROID .

Uso válido (implícito)

Estimaciones de luz de cubemap

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;

Descripciones de los miembros

  • type es el XrStructureType de esta estructura.
  • next es NULL o un puntero a la siguiente estructura en una cadena de estructuras. Las estructuras válidas son XrAmbientLightANDROID, XrSphericalHarmonicsANDROID y XrDirectionalLightANDROID .
  • state es el XrLightEstimateStateANDROID que representa el estado de la estimación de luz.
  • imageBufferSize es un uint32_t que indica el tamaño en bytes de cada búfer de imagen de rostro en el mapa de caras.
  • imageBufferRight es un búfer uint8_t que contiene la imagen de la cara derecha del mapa de cubo.
  • imageBufferLeft es un búfer uint8_t que contiene la imagen de la cara izquierda del mapa de cubo.
  • imageBufferTop es un búfer de uint8_t que contiene la imagen de la cara superior del mapa de cubo.
  • imageBufferBottom es un búfer de uint8_t que contiene la imagen de la cara inferior del mapa de cubo.
  • imageBufferFront es un búfer uint8_t que contiene la imagen de la cara frontal del mapa de cubo.
  • imageBufferBack es un búfer uint8_t que contiene la imagen de la cara posterior del mapa de cubo.
  • rotation es un XrQuaternionf que indica la rotación del mapa de cubos.
  • centerExposureTime es un XrTime que indica la hora en la que se capturó el mapa de cubo.

Esta estructura se puede encadenar a XrLightEstimateANDROID . El tiempo de ejecución solo debe completar esta estructura en xrGetLightEstimateANDROID si se usó XrCubemapLightEstimatorCreateInfoANDROID para crear el identificador del estimador de luz. La aplicación debe asignar la cantidad adecuada de memoria para los búferes de imágenes, lo que depende de los valores establecidos en XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution y XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat cuando se crea el identificador del estimador de luz. La aplicación debe establecer XrCubemapLightingDataANDROID :: imageBufferSize en la capacidad de cada búfer de imagen de la cara en bytes. Si la aplicación no usa la estimación de luz de mapa de cubos o si XrCubemapLightingDataANDROID :: imageBufferSize no es lo suficientemente grande para que el tiempo de ejecución complete los búferes de imágenes, el tiempo de ejecución debe establecer XrCubemapLightingDataANDROID :: state en XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID .

Si el conjunto de la aplicación establece XrCubemapLightEstimatorCreateInfoANDROID :: reproject en XR_TRUE cuando se crea el identificador del estimador de luz, el tiempo de ejecución debe establecer XrCubemapLightingDataANDROID :: rotation en la rotación de identidad y garantizar que el mapa de cubos interno rotado se vuelva a proyectar en las caras de un mapa de cubos de identidad en el espacio base de la aplicación.

El diseño del mapa de cubos de iluminación es el mismo que el diseño del mapa de cubos de OpenGL, como se muestra en la siguiente imagen.

Diseño de mapa de cubos de estimación de luz de XR ANDROID

Figura 24. Diseño de mapa de cubo.

Uso válido (implícito)

  • La extensión XR_ANDROID_light_estimation_cubemap debe habilitarse antes de usar XrCubemapLightingDataANDROID
  • type debe ser XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
  • next debe ser NULL o un puntero válido a la siguiente estructura en una cadena de estructuras
  • state debe ser un valor XrLightEstimateStateANDROID válido.
  • imageBufferRight debe ser un puntero a un array de valores imageBufferSize uint8_t.
  • imageBufferLeft debe ser un puntero a un array de valores imageBufferSize uint8_t.
  • imageBufferTop debe ser un puntero a un array de valores imageBufferSize uint8_t.
  • imageBufferBottom debe ser un puntero a un array de valores imageBufferSize uint8_t.
  • imageBufferFront debe ser un puntero a un array de valores imageBufferSize uint8_t.
  • imageBufferBack debe ser un puntero a un array de valores imageBufferSize uint8_t.
  • El parámetro imageBufferSize debe ser mayor que 0.

Ejemplo de código para la estimación de luz

En el siguiente ejemplo de código, se muestra cómo obtener todas las cantidades posibles de estimación de luz del tiempo de ejecución.

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

Comandos nuevos

Nuevas estructuras

Nuevas enumeraciones

Nuevas constantes de enumeración

  • XR_ANDROID_LIGHT_ESTIMATION_CUBEMAP_EXTENSION_NAME
  • XR_ANDROID_light_estimation_cubemap_SPEC_VERSION
  • Extensión de XrStructureType :

    • XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
    • XR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID
    • XR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID

Problemas

Historial de versiones

  • Revisión 1, 2025-12-05 (Salar Khan)

    • Descripción inicial de la extensión