XR_ANDROID_light_estimation_cubemap

Name String

XR_ANDROID_light_estimation_cubemap

Erweiterungstyp

Instanzerweiterung

Registrierte Durchwahlnummer

722

Revision

1

Ratifikationsstatus

Nicht ratifiziert

Abhängigkeiten von Erweiterungen und Versionen

XR_ANDROID_light_estimation

Datum der letzten Änderung

2025-08-06

IP-Status

Es sind keine Ansprüche wegen geistigen Eigentums bekannt.

Mitwirkende

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

Übersicht

Diese Erweiterung basiert auf der grundlegenden XR_ANDROID_light_estimation-Erweiterung. Es wird Unterstützung für die Schätzung der Cubemap-Beleuchtung hinzugefügt, wodurch detailliertere Schätzungen der Beleuchtung in der physischen Umgebung möglich sind.

Hinweis

Der Mechanismus zum Abrufen der Daten zur Lichtschätzung ist derselbe wie bei der einfachen Erweiterung. Allerdings muss XrCubemapLightEstimatorCreateInfoANDROID beim Erstellen des Handles für die Lichtschätzung mit XrLightEstimatorCreateInfoANDROID verkettet werden.

Systemfunktionen prüfen

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

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Solche Strukturen sind in OpenXR Core oder dieser Erweiterung nicht definiert.
  • supportsCubemapLightEstimation ist ein XrBool32, das angibt, ob das aktuelle System die Schätzung von Cubemap-Licht unterstützt.

Eine Anwendung kann prüfen, ob das System die Schätzung von Cubemap-Lichtquellen unterstützt, indem sie XrSystemProperties mit der Struktur XrSystemCubemapLightEstimationPropertiesANDROID erweitert, wenn xrGetSystemProperties aufgerufen wird .

Wenn die Laufzeit XR_FALSE für supportsCubemapLightEstimation zurückgibt und XrCubemapLightEstimatorCreateInfoANDROID an XrLightEstimatorCreateInfoANDROID angehängt wurde , muss die Laufzeit XR_ERROR_FEATURE_UNSUPPORTED von xrCreateLightEstimatorANDROID zurückgeben .

Gültige Nutzung (implizit)

Unterstützte Cubemap-Auflösungen abrufen

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

Parameterbeschreibungen

  • instance ist eine zuvor erstellte XrInstance.
  • systemId ist das XrSystemId, das zuvor von xrGetSystem abgerufen wurde und für das die unterstützten Cubemap-Auflösungen abgerufen werden sollen.
  • resolutionCapacityInput ist ein uint32_t, das die maximale Anzahl von Elementen angibt, die im Array resolutions gespeichert werden können.
  • resolutionCountOutput ist ein Zeiger auf ein uint32_t, das von der Laufzeit festgelegt wird und die Anzahl der Elemente angibt, die von der Laufzeit in das resolutions-Array geschrieben wurden.
  • resolutions ist ein Array von uint32_t, das von der Laufzeit mit den unterstützten Cubemap-Auflösungen gefüllt wird.

Die Auflösung eines Cubemaps gibt die Breite und Höhe jeder Fläche des Cubemaps in Pixeln an. 2-Call-Idiom: Die Anwendung kann dann eine der unterstützten Auflösungen in XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution verwenden, wenn das Light-Estimator-Handle erstellt wird. Die Anwendung muss basierend auf der ausgewählten Auflösung und dem Farbformat die entsprechende Menge an Arbeitsspeicher für die Bildpuffer-Member von XrCubemapLightingDataANDROID zuweisen.

Gültige Nutzung (implizit)

  •  Die XR_ANDROID_light_estimation_cubemap-Erweiterung muss aktiviert sein, bevor xrEnumerateCubemapLightingResolutionsANDROID aufgerufen wird.
  • instance muss ein gültiger XrInstance-Handle sein.
  • resolutionCountOutput muss ein Zeiger auf einen uint32_t-Wert sein.
  • Wenn resolutionCapacityInput nicht 0 ist , resolutions muss ein Zeiger auf ein Array von resolutionCapacityInput uint32_t-Werten sein.

Rückgabecodes

Erfolg

  • XR_SUCCESS

Fehler

  • 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

Unterstützte Cubemap-Farbformate abrufen

Die Enumeration XrCubemapLightingColorFormatANDROID gibt das Farbformat für die Cubemap-Beleuchtung an, das zur Laufzeit verwendet werden soll.

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;

Die Enums haben die folgenden Bedeutungen:

Enum-Beschreibung

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID

Ein Farbformat mit 3 Kanälen, wobei jeder Kanal ein 32-Bit-Gleitkommawert ist.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

Ein Farbformat mit 4 Kanälen, wobei jeder Kanal ein 32-Bit-Gleitkommawert ist.

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

Ein Farbformat mit 4 Kanälen, wobei jeder Kanal ein 16‑Bit-Gleitkommawert ist.

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

Parameterbeschreibungen

  • instance ist eine zuvor erstellte XrInstance.
  • systemId ist das XrSystemId, das zuvor von xrGetSystem abgerufen wurde und für das die unterstützten Cubemap-Auflösungen abgerufen werden sollen.
  • colorFormatCapacityInput ist ein uint32_t, das die maximale Anzahl von Elementen angibt, die im Array colorFormats gespeichert werden können.
  • colorFormatCountOutput ist ein Zeiger auf ein uint32_t, das von der Laufzeit festgelegt wird und die Anzahl der Elemente angibt, die von der Laufzeit in das colorFormats-Array geschrieben wurden.
  • colorFormats ist ein Array von XrCubemapLightingColorFormatANDROID, das von der Laufzeit mit den unterstützten Cubemap-Farbformaten gefüllt wird.

2-Call-Idiom: Die Anwendung kann dann eines der unterstützten Farbformate in XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat verwenden, wenn das Light-Estimator-Handle erstellt wird. Die Anwendung muss basierend auf dem ausgewählten Farbformat die entsprechende Menge an Arbeitsspeicher für die Bildpuffer-Member von XrCubemapLightingDataANDROID zuweisen.

Gültige Nutzung (implizit)

Rückgabecodes

Erfolg

  • XR_SUCCESS

Fehler

  • 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

Handle für Cubemap-Lichtschätzer erstellen

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

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette.
  • cubemapResolution ist ein uint32_t, der die Auflösung der zu verwendenden Cubemap-Beleuchtung angibt.
  • colorFormat ist ein XrCubemapLightingColorFormatANDROID, das das Farbformat der zu verwendenden Cubemap-Beleuchtungsdaten angibt.
  • reproject ist ein XrBool32, der angibt, ob die Cubemap-Beleuchtung in den Anwendungsbasisbereich reprojiziert werden soll.

Die Struktur XrCubemapLightEstimatorCreateInfoANDROID beschreibt die Informationen zum Erstellen eines XrLightEstimatorANDROID-Handles, das in der Lage ist, Schätzungen für die Cubemap-Beleuchtung zu liefern. Das XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution-Element muss auf eine der Auflösungen festgelegt werden, die von xrEnumerateCubemapLightingResolutionsANDROID zurückgegeben werden . Das XrCubemapLightEstimatorCreateInfoANDROID-Element :: colorFormat muss auf eines der Farbformate festgelegt werden, die von xrEnumerateCubemapLightingColorFormatsANDROID zurückgegeben werden . Wenn die Anwendung die Auflösung nicht auf eine der unterstützten Auflösungen oder das Farbformat nicht auf eines der unterstützten Farbformate festlegt, muss die Laufzeit XR_ERROR_FEATURE_UNSUPPORTED von xrCreateLightEstimatorANDROID zurückgeben .

Gültige Nutzung (implizit)

Cubemap-Lichtschätzungen

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;

Mitgliederbeschreibungen

  • type ist der XrStructureType dieser Struktur.
  • next ist NULL oder ein Zeiger auf die nächste Struktur in einer Strukturkette. Gültige Strukturen sind XrAmbientLightANDROID, XrSphericalHarmonicsANDROID und XrDirectionalLightANDROID .
  • state ist der XrLightEstimateStateANDROID, der den Status der Lichtschätzung darstellt.
  • imageBufferSize ist ein uint32_t, der die Bytegröße jedes Puffer für das Gesichtsbild im Cubemap angibt.
  • imageBufferRight ist ein uint8_t-Puffer, der das Bild der rechten Seite des Cubemaps enthält.
  • imageBufferLeft ist ein uint8_t-Puffer, der das Bild der linken Seite des Cubemaps enthält.
  • imageBufferTop ist ein uint8_t-Puffer, der das Bild der Oberseite des Cubemaps enthält.
  • imageBufferBottom ist ein uint8_t-Puffer, der das Bild der Unterseite des Cubemaps enthält.
  • imageBufferFront ist ein uint8_t-Puffer, der das Bild der Vorderseite des Cubemaps enthält.
  • imageBufferBack ist ein uint8_t-Puffer, der das Bild der Rückseite der Cubemap enthält.
  • rotation ist ein XrQuaternionf, das die Rotation der Cubemap angibt.
  • centerExposureTime ist ein XrTime, der angibt, wann die Cubemap aufgenommen wurde.

Diese Struktur kann mit XrLightEstimateANDROID verkettet werden . Die Laufzeit muss diese Struktur in xrGetLightEstimateANDROID nur dann ausfüllen, wenn das Handle des Lichtschätzers mit XrCubemapLightEstimatorCreateInfoANDROID erstellt wurde. Die Anwendung muss die entsprechende Menge an Arbeitsspeicher für die Bildpuffer zuweisen. Diese hängt von den Werten ab, die in XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution und XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat beim Erstellen des Handles für die Lichtschätzung festgelegt sind. Die Anwendung muss XrCubemapLightingDataANDROID :: imageBufferSize auf die Kapazität jedes Puffer für das Flächenbild in Byte festlegen. Wenn die Anwendung keine Cubemap-Lichtschätzung verwendet oder XrCubemapLightingDataANDROID :: imageBufferSize nicht groß genug ist, damit die Laufzeit die Bildpuffer füllen kann, muss die Laufzeit XrCubemapLightingDataANDROID :: state auf XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID festlegen .

Wenn der Anwendungssatz XrCubemapLightEstimatorCreateInfoANDROID :: reproject beim Erstellen des Light-Estimator-Handles auf XR_TRUE festgelegt ist, muss die Laufzeit XrCubemapLightingDataANDROID :: rotation auf die Identitätsrotation festlegen und dafür sorgen, dass die interne rotierte Cubemap auf die Flächen einer Identitäts-Cubemap im Anwendungsbasisbereich zurückprojiziert wird.

Das Layout der Beleuchtungs-Cubemap entspricht dem OpenGL-Cubemap-Layout, wie im folgenden Bild dargestellt.

XR ANDROID-Cubemap-Layout für die Schätzung von Licht

Abbildung 24: Cubemap-Layout

Gültige Nutzung (implizit)

  •  Die XR_ANDROID_light_estimation_cubemap-Erweiterung muss aktiviert werden, bevor XrCubemapLightingDataANDROID verwendet wird.
  • type muss XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID sein
  • next muss NULL oder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein.
  • state muss ein gültiger XrLightEstimateStateANDROID-Wert sein
  • imageBufferRight muss ein Zeiger auf ein Array von imageBufferSize uint8_t-Werten sein.
  • imageBufferLeft muss ein Zeiger auf ein Array von imageBufferSize uint8_t-Werten sein.
  • imageBufferTop muss ein Zeiger auf ein Array von imageBufferSize uint8_t-Werten sein.
  • imageBufferBottom muss ein Zeiger auf ein Array von imageBufferSize uint8_t-Werten sein.
  • imageBufferFront muss ein Zeiger auf ein Array von imageBufferSize uint8_t-Werten sein.
  • imageBufferBack muss ein Zeiger auf ein Array von imageBufferSize uint8_t-Werten sein.
  •  Der Parameter imageBufferSize muss größer als 0 sein.

Beispielcode für die Schätzung der Lichtverhältnisse

Der folgende Beispielcode zeigt, wie Sie alle möglichen Mengen für die Lichtschätzung aus der Laufzeit abrufen können.

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

Neue Befehle

Neue Strukturen

Neue Enums

Neue Enum-Konstanten

  • XR_ANDROID_LIGHT_ESTIMATION_CUBEMAP_EXTENSION_NAME
  • XR_ANDROID_light_estimation_cubemap_SPEC_VERSION
  • Erweitern von XrStructureType :

    • XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID
    • XR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID
    • XR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID

Probleme

Versionsverlauf

  • Revision 1, 05.12.2025 (Salar Khan)

    • Erste Beschreibung der Erweiterung