Реалистичное освещение виртуальных объектов в сцене.

Узнайте, как использовать Lighting Estimation в своих приложениях.

Предварительные условия

Прежде чем продолжить, убедитесь, что вы понимаете фундаментальные концепции AR и то, как настроить сеанс ARCore .

Настройте API один раз за сеанс в соответствующем режиме.

Настройте оценку освещения один раз за сеанс для режима, который вы хотите использовать.

Джава

// 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);

Котлин

// 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 окружающей среды, которые вы хотите использовать.

Джава

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

Котлин

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 , сначала избегайте выделения цветокоррекции для каждого кадра, повторно используя общее распределение.

Джава

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

Котлин

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

Получите оценку освещенности для каждого кадра, а затем получите компоненты интенсивности окружающей среды, которые вы хотите использовать.

Джава

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

Котлин

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

Обеспечение энергосбережения с помощью API-интерфейсов Environmental HDR

Сохранение энергии — это принцип, согласно которому свет, отраженный от поверхности, никогда не будет более интенсивным, чем он был до того, как достиг поверхности. Это правило применяется при физическом рендеринге, но обычно не используется в устаревших конвейерах рендеринга, используемых в видеоиграх и мобильных приложениях.

Если вы используете физический конвейер рендеринга с оценкой освещения HDR окружающей среды, просто убедитесь, что в ваших виртуальных объектах используются физически основанные материалы.

Однако если вы не используете физический конвейер, у вас есть несколько вариантов:

  • Самым идеальным решением для этой цели является переход на физический конвейер.

  • Однако, если это невозможно, хорошим обходным решением является умножение значения альбедо нефизического материала на коэффициент сохранения энергии. Это может гарантировать, что, по крайней мере , модель затенения BRDF можно будет преобразовать в физически обоснованную. Каждый BRDF имеет свой коэффициент — например, для диффузного отражения он равен 1/Pi.