XR_ANDROID_light_estimation_cubemap

Chaîne de nom

XR_ANDROID_light_estimation_cubemap

Type d'extension

Extension d'instance

Numéro d'extension enregistré

722

Révision

1

État de ratification

Non ratifié

Dépendances des extensions et des versions

XR_ANDROID_light_estimation

Date de dernière modification

2025-08-06

État de l'adresse IP

Aucune réclamation connue pour atteinte à la propriété intellectuelle.

Contributeurs

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

Présentation

Cette extension s'appuie sur l'extension XR_ANDROID_light_estimation de base. Il permet d'obtenir des estimations de l'éclairage cubemap, qui fournissent des estimations plus détaillées sur l'éclairage dans l'environnement physique.

Remarque

Le mécanisme permettant d'obtenir les données d'estimation de la luminosité est le même que pour l'extension de base, sauf que XrCubemapLightEstimatorCreateInfoANDROID doit être enchaîné à XrLightEstimatorCreateInfoANDROID lors de la création du handle d'estimateur de luminosité.

Inspecter les capacités du système

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

Descriptions des membres

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures. Aucune structure de ce type n'est définie dans l'extension ni dans le cœur d'OpenXR.
  • supportsCubemapLightEstimation est un XrBool32 qui indique si le système actuel est compatible avec l'estimation de la lumière cubemap.

Une application peut inspecter si le système est capable de prendre en charge l'estimation de la lumière cubemap en étendant XrSystemProperties avec la structure XrSystemCubemapLightEstimationPropertiesANDROID lors de l'appel de xrGetSystemProperties .

Si le runtime renvoie XR_FALSE pour supportsCubemapLightEstimation et que XrCubemapLightEstimatorCreateInfoANDROID a été chaîné à XrLightEstimatorCreateInfoANDROID , le runtime doit renvoyer XR_ERROR_FEATURE_UNSUPPORTED à partir de xrCreateLightEstimatorANDROID .

Utilisation valide (implicite)

Obtenir les résolutions de cubemaps compatibles

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

Descriptions des paramètres

  • instance est une XrInstance créée précédemment.
  • systemId correspond à XrSystemId récupéré précédemment par xrGetSystem pour lequel obtenir les résolutions de cubemap compatibles.
  • resolutionCapacityInput est un uint32_t indiquant le nombre maximal d'éléments pouvant être stockés dans le tableau resolutions.
  • resolutionCountOutput est un pointeur vers un uint32_t défini par le runtime, qui indique le nombre d'éléments écrits dans le tableau resolutions par le runtime.
  • resolutions est un tableau de uint32_t qui est renseigné par l'environnement d'exécution avec les résolutions de cubemap compatibles.

La résolution d'une cubemap indique la largeur et la hauteur de chaque face de la cubemap en pixels. Idiome à deux appels : l'application peut ensuite choisir d'utiliser l'une des résolutions compatibles dans XrCubemapLightEstimatorCreateInfoANDROID::cubemapResolution lors de la création du handle d'estimateur de lumière. L'application doit allouer la quantité de mémoire appropriée aux membres du tampon d'image de XrCubemapLightingDataANDROID en fonction de la résolution choisie et du format de couleur.

Utilisation valide (implicite)

  •  L'extension XR_ANDROID_light_estimation_cubemap doit être activée avant d'appeler xrEnumerateCubemapLightingResolutionsANDROID.
  • instance doit être un handle XrInstance valide
  • resolutionCountOutput must être un pointeur vers une valeur uint32_t
  •  Si resolutionCapacityInput n'est pas 0 , resolutions doit être un pointeur vers un tableau de valeurs uint32_t resolutionCapacityInput.

Codes de retour

Opération réussie

  • XR_SUCCESS

Échec

  • 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

Obtenir les formats de couleur cubemap compatibles

L'énumération XrCubemapLightingColorFormatANDROID indique au moteur d'exécution le format de couleur de l'éclairage cubemap à utiliser.

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;

Les énumérations ont les significations suivantes :

Description de l'enum

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID

Format de couleur à trois canaux, où chaque canal est une valeur à virgule flottante 32 bits.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

Format de couleur avec quatre canaux, où chaque canal est une valeur à virgule flottante 32 bits.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

Format de couleur avec quatre canaux, où chaque canal est une valeur flottante de 16 bits.

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

Descriptions des paramètres

  • instance est une XrInstance créée précédemment.
  • systemId correspond à XrSystemId récupéré précédemment par xrGetSystem pour lequel obtenir les résolutions de cubemap compatibles.
  • colorFormatCapacityInput est un uint32_t indiquant le nombre maximal d'éléments pouvant être stockés dans le tableau colorFormats.
  • colorFormatCountOutput est un pointeur vers un uint32_t défini par le runtime, qui indique le nombre d'éléments écrits dans le tableau colorFormats par le runtime.
  • colorFormats est un tableau de XrCubemapLightingColorFormatANDROID qui est renseigné par le runtime avec les formats de couleur de cubemap compatibles.

Idiome à deux appels : l'application peut ensuite choisir d'utiliser l'un des formats de couleur compatibles dans XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat lors de la création du handle d'estimateur de lumière. L'application doit allouer la quantité de mémoire appropriée aux membres du tampon d'image de XrCubemapLightingDataANDROID en fonction du format de couleur choisi.

Utilisation valide (implicite)

Codes de retour

Opération réussie

  • XR_SUCCESS

Échec

  • 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

Créer un handle d'estimateur de lumière cubemap

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

Descriptions des membres

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures.
  • cubemapResolution est un uint32_t qui indique la résolution de l'éclairage de la cubemap à utiliser.
  • colorFormat est un XrCubemapLightingColorFormatANDROID qui indique le format de couleur des données d'éclairage de la cubemap à utiliser.
  • reproject est un XrBool32 indiquant si l'éclairage de la cubemap doit être reprojeté dans l'espace de base de l'application.

La structure XrCubemapLightEstimatorCreateInfoANDROID décrit les informations permettant de créer un handle XrLightEstimatorANDROID capable de fournir des estimations d'éclairage de cubemap. Le membre must de XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution doit être défini sur l'une des résolutions renvoyées par xrEnumerateCubemapLightingResolutionsANDROID . Le membre XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat doit être défini sur l'un des formats de couleur renvoyés par xrEnumerateCubemapLightingColorFormatsANDROID . Si l'application ne définit pas la résolution sur l'une des résolutions compatibles ni le format de couleur sur l'un des formats de couleur compatibles, le runtime doit renvoyer XR_ERROR_FEATURE_UNSUPPORTED à partir de xrCreateLightEstimatorANDROID .

Utilisation valide (implicite)

Estimations de luminosité de la 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;

Descriptions des membres

  • type est le XrStructureType de cette structure.
  • next est NULL ou un pointeur vers la structure suivante dans une chaîne de structures. Les structures valides sont XrAmbientLightANDROID, XrSphericalHarmonicsANDROID et XrDirectionalLightANDROID .
  • state est XrLightEstimateStateANDROID, qui représente l'état de l'estimation de la luminosité.
  • imageBufferSize est un uint32_t indiquant la taille en octets de chaque tampon d'image de face dans le cubemap.
  • imageBufferRight est un tampon uint8_t contenant l'image de la face droite de la cubemap.
  • imageBufferLeft est un tampon uint8_t contenant l'image de la face gauche de la cubemap.
  • imageBufferTop est un tampon uint8_t contenant l'image de la face supérieure de la cubemap.
  • imageBufferBottom est un tampon uint8_t contenant l'image de la face inférieure de la cubemap.
  • imageBufferFront est un tampon uint8_t contenant l'image de la face avant du cubemap.
  • imageBufferBack est un tampon uint8_t contenant l'image de la face arrière de la cubemap.
  • rotation est un XrQuaternionf indiquant la rotation de la cubemap.
  • centerExposureTime est un XrTime indiquant l'heure à laquelle la cubemap a été capturée.

Cette structure peut être chaînée à XrLightEstimateANDROID . Le runtime doit uniquement remplir cette structure dans xrGetLightEstimateANDROID si XrCubemapLightEstimatorCreateInfoANDROID a été utilisé pour créer le handle d'estimateur de lumière. L'application doit allouer la quantité de mémoire appropriée pour les tampons d'image, qui dépend des valeurs définies dans XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution et XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat lors de la création du handle d'estimateur de lumière. L'application doit définir XrCubemapLightingDataANDROID :: imageBufferSize sur la capacité de chaque tampon d'image de face en octets. Si l'application n'utilise pas l'estimation de la lumière cubemap ou si XrCubemapLightingDataANDROID :: imageBufferSize n'est pas assez grand pour que le runtime remplisse les tampons d'image, le runtime doit définir XrCubemapLightingDataANDROID :: state sur XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID .

Si l'ensemble d'applications XrCubemapLightEstimatorCreateInfoANDROID :: reproject est défini sur XR_TRUE lors de la création du handle d'estimateur de lumière, le runtime doit définir XrCubemapLightingDataANDROID :: rotation sur la rotation d'identité et s'assurer que la cubemap interne pivotée est reprojetée sur les faces d'une cubemap d'identité dans l'espace de base de l'application.

La mise en page de la cubemap d'éclairage est la même que celle de la cubemap OpenGL, comme illustré dans l'image suivante.

Disposition du cubemap d'estimation de la luminosité XR ANDROID

Figure 24. Mise en page de la cubemap.

Utilisation valide (implicite)

  •  L'extension XR_ANDROID_light_estimation_cubemap doit être activée avant d'utiliser XrCubemapLightingDataANDROID.
  • type doit être XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID.
  • next doit être NULL ou un pointeur valide vers la structure suivante dans une chaîne de structures.
  • state must be a valid XrLightEstimateStateANDROID value
  • imageBufferRight must être un pointeur vers un tableau de valeurs imageBufferSize uint8_t
  • imageBufferLeft must être un pointeur vers un tableau de valeurs imageBufferSize uint8_t
  • imageBufferTop must être un pointeur vers un tableau de valeurs imageBufferSize uint8_t
  • imageBufferBottom must être un pointeur vers un tableau de valeurs imageBufferSize uint8_t
  • imageBufferFront must être un pointeur vers un tableau de valeurs imageBufferSize uint8_t
  • imageBufferBack must être un pointeur vers un tableau de valeurs imageBufferSize uint8_t
  •  Le paramètre imageBufferSize doit être supérieur à 0

Exemple de code pour l'estimation de la luminosité

L'exemple de code suivant montre comment obtenir toutes les quantités d'estimation de la luminosité possibles à partir du runtime.

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

Nouvelles commandes

Nouvelles structures

Nouveaux enums

Nouvelles constantes d'énumération

  • XR_ANDROID_LIGHT_ESTIMATION_CUBEMAP_EXTENSION_NAME
  • XR_ANDROID_light_estimation_cubemap_SPEC_VERSION
  • Extension de XrStructureType :

    • XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
    • XR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID
    • XR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID

Problèmes

Historique des versions

  • Révision 1, 05/12/2025 (Salar Khan)

    • Description initiale de l'extension