XR_ANDROID_light_estimation_cubemap

Name String

XR_ANDROID_light_estimation_cubemap

拡張機能のタイプ

インスタンス拡張機能

Registered Extension Number

722

リビジョン

1

Ratification Status(批准ステータス)

未批准

拡張機能とバージョンの依存関係

XR_ANDROID_light_estimation

最終更新日

2025-08-06

IP ステータス

既知の 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 拡張機能をベースにしています。キューブマップ照明の推定値を取得するサポートが追加され、物理環境の照明に関するより詳細な推定値が提供されます。

光推定データを取得するメカニズムは基本拡張機能と同じですが、光推定ハンドルの作成時に XrCubemapLightEstimatorCreateInfoANDROIDXrLightEstimatorCreateInfoANDROID にチェーンする必要があります。

システムの性能を検査する

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

メンバーの説明

  • type は、この構造の XrStructureType です。
  • next は、NULL または構造体チェーン内の次の構造体へのポインタです。コア OpenXR またはこの拡張機能では、このような構造は定義されていません。
  • supportsCubemapLightEstimationXrBool32 で、現在のシステムがキューブマップ ライト推定をサポートしているかどうかを示します。

アプリケーションは、xrGetSystemProperties を呼び出すときに XrSystemPropertiesXrSystemCubemapLightEstimationPropertiesANDROID 構造体で拡張することで、システムがキューブマップ ライト推定をサポートできるかどうかを検査できます

ランタイムが supportsCubemapLightEstimation に対して XR_FALSE を返し、XrCubemapLightEstimatorCreateInfoANDROIDXrLightEstimatorCreateInfoANDROID にチェーンされている場合、ランタイムは xrCreateLightEstimatorANDROID から XR_ERROR_FEATURE_UNSUPPORTED を返さなければなりません。

有効な使用方法(暗黙的)

サポートされているキューブマップの解像度を取得する

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

パラメータの説明

  • instance は、以前に作成した XrInstance です。
  • systemId は、サポートされているキューブマップ解像度を取得する対象の、xrGetSystem によって以前に取得された XrSystemId です。
  • resolutionCapacityInput は、resolutions 配列に格納できる要素の最大数を示す uint32_t です。
  • resolutionCountOutputuint32_t へのポインタです。これは、ランタイムによって設定され、ランタイムによって resolutions 配列に書き込まれた要素の数を示します。
  • resolutionsuint32_t の配列で、ランタイムによってサポートされているキューブマップの解像度が入力されます。

キューブマップの解像度は、キューブマップの各面の幅と高さをピクセル単位で示します。2 回呼び出しのイディオム: アプリは、ライト エスティメータ ハンドルを作成する際に、XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution でサポートされている解像度のいずれかを使用することを選択できます。アプリは、選択した解像度とカラー形式に基づいて、XrCubemapLightingDataANDROID の画像バッファ メンバーに適切な量のメモリを割り当てる必要があります

有効な使用方法(暗黙的)

  • xrEnumerateCubemapLightingResolutionsANDROID を呼び出す前に、XR_ANDROID_light_estimation_cubemap 拡張機能を有効にする必要があります。
  • instance は、有効な XrInstance ハンドルでなければなりません。
  • resolutionCountOutputuint32_t 値へのポインタでなければなりません。
  • resolutionCapacityInput0 でない場合、resolutionsresolutionCapacityInput 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 ビット浮動小数点値である 3 チャンネルのカラー形式。

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID

各チャンネルが 32 ビット浮動小数点値である 4 チャンネルのカラー形式。

XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID

各チャンネルが 16 ビットの浮動小数点値である 4 チャンネルのカラー形式。

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

パラメータの説明

  • instance は、以前に作成した XrInstance です。
  • systemId は、サポートされているキューブマップ解像度を取得する対象の、xrGetSystem によって以前に取得された XrSystemId です。
  • colorFormatCapacityInput は、colorFormats 配列に格納できる要素の最大数を示す uint32_t です。
  • colorFormatCountOutputuint32_t へのポインタです。これは、ランタイムによって設定され、ランタイムによって colorFormats 配列に書き込まれた要素の数を示します。
  • colorFormatsXrCubemapLightingColorFormatANDROID の配列です。ランタイムによって、サポートされているキューブマップの色形式が入力されます。

2 回呼び出しのイディオム アプリは、ライト エスティメータ ハンドルを作成するときに、XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat でサポートされている色形式のいずれかを使用することを選択できます。アプリは、選択されたカラー形式に基づいて、XrCubemapLightingDataANDROID の画像バッファ メンバーに適切な量のメモリを割り当てる必要があります

有効な使用方法(暗黙的)

  • xrEnumerateCubemapLightingColorFormatsANDROID を呼び出す前に、XR_ANDROID_light_estimation_cubemap 拡張機能を有効にする必要があります。
  • instance は、有効な XrInstance ハンドルでなければなりません。
  • colorFormatCountOutputuint32_t 値へのポインタでなければなりません。
  • colorFormatCapacityInput0 でない場合、colorFormatscolorFormatCapacityInput 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 が返す解像度のいずれかに設定されなければなりませんXrCubemapLightEstimatorCreateInfoANDROID :: colorFormat メンバーは、xrEnumerateCubemapLightingColorFormatsANDROID が返すカラー形式のいずれかに設定しなければなりません。アプリケーションが解像度をサポートされている解像度のいずれかに設定していない場合、またはカラー形式をサポートされているカラー形式のいずれかに設定していない場合、ランタイムは xrCreateLightEstimatorANDROID から XR_ERROR_FEATURE_UNSUPPORTED を返さなければなりません

有効な使用方法(暗黙的)

キューブマップの光の推定

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 または構造体チェーン内の次の構造体へのポインタです。有効な構造は、XrAmbientLightANDROIDXrSphericalHarmonicsANDROIDXrDirectionalLightANDROID です。
  • 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 にチェーンできます。ランタイムは、XrCubemapLightEstimatorCreateInfoANDROID を使用してライト推定ハンドルの作成が行われた場合にのみ、xrGetLightEstimateANDROID でこの構造体を設定しなければなりません。アプリケーションは、ライト エスティメータ ハンドルを作成するときに、XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolutionXrCubemapLightEstimatorCreateInfoANDROID :: colorFormat で設定された値に応じて、画像バッファに適切な量のメモリを割り当てなければなりません。アプリケーションは、XrCubemapLightingDataANDROID :: imageBufferSize を各面画像バッファの容量(バイト単位)に設定しなければなりません。アプリがキューブマップ ライト推定を使用していない場合、または XrCubemapLightingDataANDROID :: imageBufferSize がランタイムで画像バッファを読み込むのに十分な大きさでない場合、ランタイムは XrCubemapLightingDataANDROID :: stateXR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID に設定しなければなりません。

アプリケーションがライト エスティメータ ハンドルの作成時に XrCubemapLightEstimatorCreateInfoANDROID :: reprojectXR_TRUE に設定した場合、ランタイムは XrCubemapLightingDataANDROID :: rotation を単位回転に設定し、内部回転したキューブマップがアプリケーションのベース空間の単位キューブマップの面に再投影されるようにしなければなりません

ライティング キューブマップのレイアウトは、次の画像に示すように、OpenGL キューブマップのレイアウトと同じです。

XR ANDROID の光推定キューブマップ レイアウト

図 24. キューブマップ レイアウト。

有効な使用方法(暗黙的)

  • XrCubemapLightingDataANDROID を使用する前に、XR_ANDROID_light_estimation_cubemap 拡張機能を有効にする必要があります。
  • typeXR_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、2025-12-05(Salar Khan)

    • 拡張機能の最初の説明