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 deseas 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 para cada fotograma y, luego, obtén los componentes de iluminación HDR ambiental que deseas 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 color del modo AMBIENT_INTENSITY, primero evita la asignación de corrección de color 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 para cada fotograma y, luego, obtén los componentes de intensidad ambiental que deseas 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)
}
Cómo garantizar la conservación de energía con las APIs de HDR ambiental
La conservación de energía es el principio de que la luz reflejada desde una superficie nunca será más intensa que antes de que llegue a la superficie. Esta regla se aplica en la renderización basada en la física, pero, por lo general, se omite de las canalizaciones de renderización heredadas 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 la 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 uno basado en la física. Cada BRDF tiene un factor diferente; por ejemplo, para una reflexión difusa, es 1/Pi.