Objetos virtuales realistas en una escena

Aprende a usar la Estimación de iluminación en tus propias apps.

Requisitos previos

Antes de continuar, asegúrate de comprender los conceptos fundamentales de la RA y cómo configurar una sesión de ARCore.

Configura la API una vez por sesión con el modo adecuado

Configura la Estimación de iluminación una vez por sesión para el modo que quieras usar.

HDR ambiental

// Configure the session's lighting estimation mode for
// AR_LIGHT_ESTIMATION_MODE_ENVIRONMENTAL_HDR.
ArConfig* config = NULL;
ArConfig_create(session, &config);
ArSession_getConfig(session, config);
ArConfig_setLightEstimationMode(session, config,
                                AR_LIGHT_ESTIMATION_MODE_ENVIRONMENTAL_HDR);
ArSession_configure(session, config);
ArConfig_destroy(config);

Intensidad ambiental

// Configure the session's lighting estimation mode for
// AR_LIGHT_ESTIMATION_MODE_AMBIENT_INTENSITY.
ArConfig* config = NULL;
ArConfig_create(session, &config);
ArSession_getConfig(session, config);
ArConfig_setLightEstimationMode(session, config,
                                AR_LIGHT_ESTIMATION_MODE_AMBIENT_INTENSITY);
ArSession_configure(session, config);
ArConfig_destroy(config);

Inhabilitado

// Disable the session's lighting estimation mode.
ArConfig* config = NULL;
ArConfig_create(session, &config);
ArSession_getConfig(session, config);
ArConfig_setLightEstimationMode(session, config,
                                AR_LIGHT_ESTIMATION_MODE_DISABLED);
ArSession_configure(session, config);
ArConfig_destroy(config);

Usar los valores obtenidos de la Estimación de iluminación

Para usar los valores obtenidos de la Estimación de iluminación, obtén la estimación de luz para cada fotograma.

// Get the current frame.
ArFrame* ar_frame = NULL;
if (ArSession_update(session, ar_frame) != AR_SUCCESS) {
  LOGE("ArSession_update error");
  return;
}

// Get the light estimate for the current frame.
ArLightEstimate* ar_light_estimate = NULL;
ArLightEstimate_create(session, &ar_light_estimate);
ArFrame_getLightEstimate(session, ar_frame, ar_light_estimate);

ArLightEstimateState ar_light_estimate_state;
ArLightEstimate_getState(session, ar_light_estimate,
                         &ar_light_estimate_state);

// Check that the light estimate is valid before proceeding.
if (ar_light_estimate_state != AR_LIGHT_ESTIMATE_STATE_VALID) {
  LOGE("ArLightEstimateState is not valid.");
  ArLightEstimate_destroy(ar_light_estimate);
  return;
}

Luego, obtén los componentes de iluminación HDR ambiental para la configuración actual:

HDR ambiental

// Get intensity and direction of the main directional light from the current
// light estimate.
float direction[3];
ArLightEstimate_getEnvironmentalHdrMainLightDirection(
    session, ar_light_estimate, direction);

float intensity[3];
ArLightEstimate_getEnvironmentalHdrMainLightIntensity(
    session, ar_light_estimate, intensity);

// Get ambient lighting as spherical harmonics coefficients.
float ambient_spherical_harmonics[27];
ArLightEstimate_getEnvironmentalHdrAmbientSphericalHarmonics(
    session, ar_light_estimate, ambient_spherical_harmonics);

// Get HDR environmental lighting as a cubemap in linear color space.
ArImageCubemap cubemap_textures;
ArLightEstimate_acquireEnvironmentalHdrCubemap(session, ar_light_estimate,
                                               cubemap_textures);
int width = -1;
int height = -1;
int32_t format = -1;
for (int i = 0; i < 6; ++i) {
  ArImage* image_ptr = cubemap_textures[i];
  // We can access the cubemap texture data through ArImage APIs.
  ArImage_getWidth(session, image_ptr, &width);
  ArImage_getHeight(session, image_ptr, &height);
  ArImage_getFormat(session, image_ptr, &format);
  // Acquired image must be released with ArImage_release once it is no
  // longer needed.
  ArImage_release(image_ptr);
}
ArLightEstimate_destroy(ar_light_estimate);

Intensidad ambiental

// Get the pixel intensity of AR_LIGHT_ESTIMATION_MODE_AMBIENT_INTENSITY mode.
float pixel_intensity;
ArLightEstimate_getPixelIntensity(session, ar_light_estimate,
                                  &pixel_intensity);

// Get the pixel color correction of
// AR_LIGHT_ESTIMATION_MODE_AMBIENT_INTENSITY mode.
float color_correction[4];
ArLightEstimate_getColorCorrection(session, ar_light_estimate,
                                   color_correction);
ArLightEstimate_destroy(ar_light_estimate);

Cómo garantizar la conservación de energía con las APIs de HDR ambiental

La conservación de energía es el principio que establece que la luz reflejada en una superficie nunca será más intensa que antes de llegar a la superficie. Esta regla se aplica en el renderizado basado en la física, pero suele omitirse en las canalizaciones de renderizado heredadas que se utilizan en videojuegos y apps para dispositivos móviles.

Si usas una canalización de renderización basada en la física con estimación de luz HDR ambiental, asegúrate de que se usen materiales basados en la física en tus objetos virtuales.

Sin embargo, si no usas una canalización basada en la física, tienes algunas opciones:

  • La solución más ideal para esto es migrar a una canalización basada en la física.

  • Sin embargo, si eso no es posible, una buena solución alternativa es multiplicar el valor de albedo de un material no basado en la física por un factor de conservación de energía. Esto puede garantizar que, al menos, el modelo de sombreado BRDF se pueda convertir en un modelo basado en la física. Cada BRDF tiene un factor diferente. Por ejemplo, para una reflexión difusa, es 1/Pi.