XR_ANDROID_light_estimation_cubemap

String de nome

XR_ANDROID_light_estimation_cubemap

Tipo de extensão

Extensão de instância

Número da extensão registrada

722

Revisão

1

Status de ratificação

Não ratificado

Dependências de extensão e versão

XR_ANDROID_light_estimation

Data da última modificação

06/08/2025

Status do IP

Não há reivindicações de IP conhecidas.

Colaboradores

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

Visão geral

Essa extensão se baseia na extensão básica XR_ANDROID_light_estimation. Ele adiciona suporte para receber estimativas de iluminação de cubo, que fornecem estimativas mais detalhadas sobre a iluminação no ambiente físico.

Observação

O mecanismo para receber os dados de estimativa de luz é o mesmo da extensão básica, exceto que XrCubemapLightEstimatorCreateInfoANDROID precisa ser encadeado ao XrLightEstimatorCreateInfoANDROID ao criar o identificador do estimador de luz.

Inspecionar a capacidade do sistema

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

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. Nenhuma dessas estruturas é definida no OpenXR principal ou nesta extensão.
  • supportsCubemapLightEstimation é um XrBool32 que indica se o sistema atual é compatível com a estimativa de iluminação do cubo.

Um aplicativo pode inspecionar se o sistema é capaz de oferecer suporte à estimativa de iluminação do cubo estendendo XrSystemProperties com a estrutura XrSystemCubemapLightEstimationPropertiesANDROID ao chamar xrGetSystemProperties .

Se o tempo de execução retornar XR_FALSE para supportsCubemapLightEstimation e XrCubemapLightEstimatorCreateInfoANDROID tiver sido encadeado a XrLightEstimatorCreateInfoANDROID , o tempo de execução deverá retornar XR_ERROR_FEATURE_UNSUPPORTED de xrCreateLightEstimatorANDROID .

Uso válido (implícito)

Como receber resoluções de cubo compatíveis

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

Descrições dos parâmetros

  • instance é uma XrInstance criada anteriormente.
  • systemId é o XrSystemId recuperado anteriormente por xrGetSystem para receber as resoluções de cubo compatíveis.
  • resolutionCapacityInput é um uint32_t que indica o número máximo de elementos que podem ser armazenados na matriz resolutions.
  • resolutionCountOutput é um ponteiro para um uint32_t definido pelo tempo de execução, indicando o número de elementos gravados na matriz resolutions pelo tempo de execução.
  • resolutions é uma matriz de uint32_t preenchida pelo ambiente de execução com as resoluções de cubo aceitas.

Uma resolução de cubemap indica a largura e a altura de cada face do cubemap em pixels. Expressão de duas chamadas: o aplicativo pode usar uma das resoluções compatíveis em XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution ao criar o identificador do estimador de luz. O aplicativo precisa alocar a quantidade adequada de memória para os membros do buffer de imagem de XrCubemapLightingDataANDROID com base na resolução escolhida e no formato de cor.

Uso válido (implícito)

  • A extensão XR_ANDROID_light_estimation_cubemap precisa ser ativada antes de chamar xrEnumerateCubemapLightingResolutionsANDROID.
  • instance precisa ser um identificador XrInstance válido
  • resolutionCountOutput precisa ser um ponteiro para um valor uint32_t.
  • Se resolutionCapacityInput não for 0 , resolutions precisa ser um ponteiro para uma matriz de valores resolutionCapacityInput uint32_t.

Códigos de retorno

Sucesso

  • XR_SUCCESS

Falha

  • 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

Como receber formatos de cores de cubo compatíveis

A enumeração XrCubemapLightingColorFormatANDROID identifica para o ambiente de execução o formato de cor da iluminação do cubo a ser usado.

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;

Os tipos enumerados têm os seguintes significados:

Descrição da enumeração

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID

Um formato de cor com três canais, em que cada um é um valor de ponto flutuante de 32 bits.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

Um formato de cor com quatro canais em que cada um é um valor de ponto flutuante de 32 bits.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

Um formato de cor com quatro canais, em que cada um é um valor de ponto flutuante de 16 bits.

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

Descrições dos parâmetros

  • instance é uma XrInstance criada anteriormente.
  • systemId é o XrSystemId recuperado anteriormente por xrGetSystem para receber as resoluções de cubo compatíveis.
  • colorFormatCapacityInput é um uint32_t que indica o número máximo de elementos que podem ser armazenados na matriz colorFormats.
  • colorFormatCountOutput é um ponteiro para um uint32_t definido pelo tempo de execução, indicando o número de elementos gravados na matriz colorFormats pelo tempo de execução.
  • colorFormats é uma matriz de XrCubemapLightingColorFormatANDROID preenchida pelo tempo de execução com os formatos de cor de cubo compatíveis.

Idioma de duas chamadas: o aplicativo pode escolher usar um dos formatos de cor compatíveis em XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat ao criar o identificador do estimador de luz. O aplicativo precisa alocar a quantidade adequada de memória para os membros do buffer de imagem de XrCubemapLightingDataANDROID com base no formato de cor escolhido.

Uso válido (implícito)

Códigos de retorno

Sucesso

  • XR_SUCCESS

Falha

  • 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

Criar um handle para estimador de iluminação de cubemap

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

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • cubemapResolution é um uint32_t que indica a resolução da iluminação do cubo para usar.
  • colorFormat é um XrCubemapLightingColorFormatANDROID que indica o formato de cor dos dados de iluminação do cubo a serem usados.
  • reproject é um XrBool32 que indica se a iluminação do cubo deve ser reprojetada para o espaço base do aplicativo.

A estrutura XrCubemapLightEstimatorCreateInfoANDROID descreve as informações para criar um identificador XrLightEstimatorANDROID capaz de fornecer estimativas de iluminação de cubo. O membro must cubemapResolution de XrCubemapLightEstimatorCreateInfoANDROID precisa ser definido como uma das resoluções retornadas por xrEnumerateCubemapLightingResolutionsANDROID . O membro colorFormat de XrCubemapLightEstimatorCreateInfoANDROID precisa ser definido como um dos formatos de cor retornados por xrEnumerateCubemapLightingColorFormatsANDROID . Se o aplicativo não definir a resolução como uma das resoluções compatíveis ou o formato de cor como um dos formatos compatíveis, o tempo de execução deverá retornar XR_ERROR_FEATURE_UNSUPPORTED de xrCreateLightEstimatorANDROID .

Uso válido (implícito)

Estimativas de luz do 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;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas. As estruturas válidas são XrAmbientLightANDROID, XrSphericalHarmonicsANDROID e XrDirectionalLightANDROID .
  • state é o XrLightEstimateStateANDROID que representa o estado da estimativa de luz.
  • imageBufferSize é um uint32_t que indica o tamanho do byte de cada buffer de imagem de rosto no cubemap.
  • imageBufferRight é um buffer uint8_t que contém a imagem da face direita do cubemap.
  • imageBufferLeft é um buffer uint8_t que contém a imagem da face esquerda do cubemap.
  • imageBufferTop é um buffer uint8_t que contém a imagem da face superior do cubemap.
  • imageBufferBottom é um buffer uint8_t que contém a imagem da face inferior do cubemap.
  • imageBufferFront é um buffer uint8_t que contém a imagem da face frontal do cubemap.
  • imageBufferBack é um buffer uint8_t que contém a imagem da face traseira do cubo.
  • rotation é um XrQuaternionf que indica a rotação do cubemap.
  • centerExposureTime é um XrTime que indica o momento em que o cubemap foi capturado.

Essa estrutura pode ser encadeada ao XrLightEstimateANDROID . O tempo de execução deve preencher essa estrutura em xrGetLightEstimateANDROID se o XrCubemapLightEstimatorCreateInfoANDROID foi usado para criar o identificador do estimador de luz. O aplicativo precisa alocar a quantidade adequada de memória para os buffers de imagem, que depende dos valores definidos em XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution e XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat ao criar o identificador do estimador de luz. O aplicativo precisa definir XrCubemapLightingDataANDROID :: imageBufferSize como a capacidade de cada buffer de imagem de face em bytes. Se o aplicativo não estiver usando a estimativa de iluminação do cubemap ou se XrCubemapLightingDataANDROID :: imageBufferSize não for grande o suficiente para o tempo de execução preencher os buffers de imagem, o tempo de execução deverá definir XrCubemapLightingDataANDROID :: state como XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID .

Se o aplicativo definir XrCubemapLightEstimatorCreateInfoANDROID :: reproject como XR_TRUE ao criar o identificador do estimador de luz, o tempo de execução deverá definir XrCubemapLightingDataANDROID :: rotation como a rotação de identidade e garantir que o cubo de ambiente girado interno seja reprojetado nas faces de um cubo de ambiente de identidade no espaço de base do aplicativo.

O layout do cubemap de iluminação é o mesmo do layout do cubemap do OpenGL, conforme mostrado na imagem a seguir.

Layout do cubo de estimação de luz do XR ANDROID

Figura 24. Layout do cubo.

Uso válido (implícito)

  • A extensão XR_ANDROID_light_estimation_cubemap precisa ser ativada antes de usar XrCubemapLightingDataANDROID.
  • type precisa ser XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
  • next precisa ser NULL ou um ponteiro válido para a próxima estrutura em uma cadeia de estruturas.
  • state precisa ser um valor XrLightEstimateStateANDROID válido
  • imageBufferRight precisa ser um ponteiro para uma matriz de valores imageBufferSize uint8_t.
  • imageBufferLeft precisa ser um ponteiro para uma matriz de valores imageBufferSize uint8_t.
  • imageBufferTop precisa ser um ponteiro para uma matriz de valores imageBufferSize uint8_t.
  • imageBufferBottom precisa ser um ponteiro para uma matriz de valores imageBufferSize uint8_t.
  • imageBufferFront precisa ser um ponteiro para uma matriz de valores imageBufferSize uint8_t.
  • imageBufferBack precisa ser um ponteiro para uma matriz de valores imageBufferSize uint8_t.
  • O parâmetro imageBufferSize precisa ser maior que 0

Exemplo de código para estimativa de iluminação

O exemplo de código a seguir demonstra como extrair todas as quantidades possíveis de estimativa de iluminação do tempo de execução.

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

Novos comandos

Novas estruturas

Novos tipos enumerados

Novas constantes de enumeração

  • XR_ANDROID_LIGHT_ESTIMATION_CUBEMAP_EXTENSION_NAME
  • XR_ANDROID_light_estimation_cubemap_SPEC_VERSION
  • Extensão 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

Histórico de versões

  • Revisão 1, 05/12/2025 (Salar Khan)

    • Descrição inicial da extensão