独自のアプリで照明の推定を使用する方法を学びます。
前提条件
続行する前に、基本的な AR のコンセプトと ARCore セッションの構成方法を理解しておいてください。
適切なモードでセッションごとに 1 回 API を構成する
使用するモードのライティング推定をセッションごとに 1 回構成します。
Java
// Configure the session with the Lighting Estimation API in ENVIRONMENTAL_HDR mode.
Config config = session.getConfig();
config.setLightEstimationMode(LightEstimationMode.ENVIRONMENTAL_HDR);
session.configure(config);
// Configure the session with the Lighting Estimation API in AMBIENT_INTENSITY mode.
Config config = session.getConfig();
config.setLightEstimationMode(LightEstimationMode.AMBIENT_INTENSITY);
session.configure(config);
// Configure the session with the Lighting Estimation API turned off.
Config config = session.getConfig();
config.setLightEstimationMode(LightEstimationMode.DISABLED);
session.configure(config);
Kotlin
// Configure the session with the Lighting Estimation API in ENVIRONMENTAL_HDR mode.
Config config = session.config
config.lightEstimationMode = LightEstimationMode.ENVIRONMENTAL_HDR
session.configure(config)
// Configure the session with the Lighting Estimation API in AMBIENT_INTENSITY mode.
Config config = session.config
config.lightEstimationMode = LightEstimationMode.AMBIENT_INTENSITY
session.configure(config)
// Configure the session with the Lighting Estimation API turned off.
Config config = session.config
config.lightEstimationMode = LightEstimationMode.DISABLED
session.configure(config)
ENVIRONMENTAL_HDR モードを構成する
ENVIRONMENTAL_HDR モードを構成するには、各フレームの光の推定値を取得してから、使用する環境 HDR 照明コンポーネントを取得します。
Java
void update() {
// Get the current frame.
Frame frame = session.update();
// Get the light estimate for the current frame.
LightEstimate lightEstimate = frame.getLightEstimate();
// Get intensity and direction of the main directional light from the current light estimate.
float[] intensity = lightEstimate.getEnvironmentalHdrMainLightIntensity(); // note - currently only out param.
float[] direction = lightEstimate.getEnvironmentalHdrMainLightDirection();
app.setDirectionalLightValues(intensity, direction); // app-specific code.
// Get ambient lighting as spherical harmonics coefficients.
float[] harmonics = lightEstimate.getEnvironmentalHdrAmbientSphericalHarmonics();
app.setAmbientSphericalHarmonicsLightValues(harmonics); // app-specific code.
// Get HDR environmental lighting as a cubemap in linear color space.
Image[] lightmaps = lightEstimate.acquireEnvironmentalHdrCubeMap();
for (int i = 0; i < lightmaps.length /*should be 6*/; ++i) {
app.uploadToTexture(i, lightmaps[i]); // app-specific code.
}
}
Kotlin
fun update() {
// Get the current frame.
val frame = session.update()
// Get the light estimate for the current frame.
val lightEstimate = frame.lightEstimate
// Get intensity and direction of the main directional light from the current light estimate.
val intensity = lightEstimate.environmentalHdrMainLightIntensity
val direction = lightEstimate.environmentalHdrMainLightDirection
app.setDirectionalLightValues(intensity, direction) // app-specific code.
// Get ambient lighting as spherical harmonics coefficients.
val harmonics = lightEstimate.environmentalHdrAmbientSphericalHarmonics
app.ambientSphericalHarmonicsLightValues = harmonics // app-specific code.
// Get HDR environmental lighting as a cubemap in linear color space.
val lightMaps = lightEstimate.acquireEnvironmentalHdrCubeMap();
for ((index, lightMap) in lightMaps.withIndex()) { // 6 maps total.
app.uploadToTexture(index, lightMap); // app-specific code.
}
}
AMBIENT_INTENSITY モードを構成する
AMBIENT_INTENSITY モードの色補正コンポーネントを使用する場合は、まず共有割り当てを再利用して、すべてのフレームで色補正の割り当てを回避します。
Java
// Avoid allocation on every frame.
float[] colorCorrection = new float[4];
Kotlin
val colorCorrection = floatArrayOf(0.0f, 0.0f, 0.0f, 0.0f)
各フレームの光の推定値を取得し、使用するアンビエント強度コンポーネントを取得します。
Java
void update() {
// Get the current frame.
Frame frame = session.update();
// Get the light estimate for the current frame.
LightEstimate lightEstimate = frame.getLightEstimate();
// Get the pixel intensity of AMBIENT_INTENSITY mode.
float pixelIntensity = lightEstimate.getPixelIntensity();
// Read the pixel color correction of AMBIENT_INTENSITY mode into colorCorrection.
lightEstimate.getColorCorrection(colorCorrection, 0);
}
Kotlin
fun update() {
// Get the current frame.
val frame = session.update()
// Get the light estimate for the current frame.
val lightEstimate = frame.lightEstimate
// Get the pixel intensity of AMBIENT_INTENSITY mode.
val pixelIntensity = lightEstimate.pixelIntensity
// Read the pixel color correction of AMBIENT_INTENSITY mode into colorCorrection.
lightEstimate.getColorCorrection(colorCorrection, 0)
}
環境 HDR API による省エネの実現
エネルギー保存の法則とは、表面で反射した光の強度が、表面に当たる前よりも強くなることはないという原則です。このルールは物理ベース レンダリングで適用されますが、ビデオゲームやモバイルアプリで使用される従来のレンダリング パイプラインでは通常省略されます。
環境 HDR ライト推定で物理ベースのレンダリング パイプラインを使用している場合は、仮想オブジェクトで物理ベースのマテリアルが使用されていることを確認するだけです。
ただし、物理ベースのパイプラインを使用していない場合は、次の 2 つのオプションがあります。
この場合の最適な解決策は、物理ベースのパイプラインに移行することです。
ただし、それが不可能な場合は、物理ベースでないマテリアルのアルベド値にエネルギー保存係数を乗算するのが適切な回避策です。これにより、少なくとも BRDF シェーディング モデルを物理ベースに変換できます。各 BRDF には異なる係数があります。たとえば、拡散反射の場合は 1/Pi です。