Objetos virtuales realistas en una escena

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

Requisitos previos

Asegúrate de comprender los conceptos fundamentales de RA y cómo configurar una sesión de ARCore antes de continuar.

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.

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)

Configura el modo ENVIRONMENTAL_HDR

Para configurar el modo ENVIRONMENTAL_HDR, obtén la estimación de luz de cada fotograma. y obtener los componentes de iluminación HDR del entorno que quieras usar.

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.
  }
}

Configura el modo AMBIENT_INTENSITY

Si planeas usar el componente de corrección de colores de AMBIENT_INTENSITY , primero evita la asignación de corrección de colores en cada fotograma reutilizando una asignación compartida.

Java

 // Avoid allocation on every frame.
float[] colorCorrection = new float[4];

Kotlin

val colorCorrection = floatArrayOf(0.0f, 0.0f, 0.0f, 0.0f)

Obtén la estimación de luz de cada fotograma y, luego, los componentes de intensidad ambiental que quieres usar.

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

Garantizar la conservación de la energía con las APIs de HDR de impacto ambiental

La conservación de la energía es el principio de que la luz reflejada desde una superficie nunca ser más intensa que antes de salir a la superficie. Esta regla es se aplican en renderizaciones basadas en elementos físicos, pero suelen omitirse de las versiones heredadas. canalizaciones de renderización que se usan 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, solo asegúrate de que se usen materiales basados en la física en tus objetos virtuales.

Sin embargo, si no usa una canalización física, hay 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 del BRDF se pueden convertir en servicios físicos. Cada BRDF tiene un factor diferente. Por ejemplo, para una reflexión difusa, es 1/Pi.