Aprenda a usar a estimativa de iluminação (em inglês). nos seus próprios apps.
Pré-requisitos
Entenda os conceitos básicos de RA e como configurar uma sessão do ARCore antes de continuar.
Configurar a API uma vez por sessão com o modo apropriado
Configure a estimativa de iluminação uma vez por sessão para o modo que você quer 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)
Configurar o modo ENVIRONMENTAL_HDR
Para configurar o modo ENVIRONMENTAL_HDR
, confira a estimativa de luz para cada frame,
e acesse os componentes de iluminação HDR do ambiente que você quer 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.
}
}
Configurar o modo AMBIENT_INTENSITY
Se você planeja usar o componente de correção de cor do modo AMBIENT_INTENSITY
,
evite primeiro a alocação de correção de cor em cada frame reutilizando uma alocação compartilhada.
Java
// Avoid allocation on every frame.
float[] colorCorrection = new float[4];
Kotlin
val colorCorrection = floatArrayOf(0.0f, 0.0f, 0.0f, 0.0f)
Confira a estimativa de luz para cada frame e depois confira os componentes de intensidade do ambiente que você quer 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)
}
Garantir a conservação de energia com as APIs Environmental HDR
Conservação de energia é o princípio segundo o qual a luz refletida de uma superfície nunca será mais intensa do que antes de atingir a superfície. Esta regra é aplicadas em renderização com base física, mas geralmente são omitidos do código pipelines de renderização usados em videogames e apps para dispositivos móveis.
Se você estiver usando um pipeline de renderização baseado fisicamente com o Environmental HDR a estimativa de luz, simplesmente garanta que materiais com base física sejam usados em seu objetos virtuais.
No entanto, se não estiver usando um pipeline baseado fisicamente, você terá algumas opções:
A solução ideal para isso é migrar para um pipeline baseado fisicamente.
No entanto, se isso não for possível, uma boa solução é multiplicar o valor de albedo de um material sem base física por uma conservação de energia fator Isso pode garantir que pelo menos o modelo de sombreamento BRDF podem ser convertidos em físicos. Cada BRDF tem um fator diferente, por exemplo, para uma reflexão difusa, é 1/Pi.