ให้แสงวัตถุเสมือนจริงในฉากอย่างสมจริง

เรียนรู้วิธีใช้การประมาณแสงในแอปของคุณเอง

ข้อกำหนดเบื้องต้น

ตรวจสอบว่าคุณเข้าใจแนวคิด AR พื้นฐาน และวิธีกำหนดค่าเซสชัน ARCore ก่อนดำเนินการต่อ

กำหนดค่า API 1 ครั้งต่อเซสชันด้วยโหมดที่เหมาะสม

กำหนดค่าการประมาณการให้แสง 1 ครั้งต่อเซสชันสำหรับโหมดที่ต้องการใช้

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)

กำหนดค่าโหมด ENVIRONMENTAL_HDR

หากต้องการกำหนดค่าโหมด ENVIRONMENTAL_HDR ให้รับค่าประมาณของแสงสำหรับแต่ละเฟรม แล้วรับคอมโพเนนต์แสง HDR สภาพแวดล้อมที่คุณต้องการใช้

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

กำหนดค่าโหมด AMBIENT_INTENSITY

หากกำลังวางแผนที่จะใช้คอมโพเนนต์การแก้สีของโหมด AMBIENT_INTENSITY โปรดหลีกเลี่ยงการจัดสรรการแก้สีในทุกเฟรมด้วยการจัดสรรที่แชร์ซ้ำก่อน

Java

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

Kotlin

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

รับค่าประมาณของแสงสำหรับแต่ละเฟรม แล้วรับคอมโพเนนต์ความเข้มแวดล้อม ที่ต้องการใช้

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

รับประกันการอนุรักษ์พลังงานด้วย Environmental HDR API

การอนุรักษ์พลังงานคือหลักการที่ว่าแสงที่สะท้อนจากพื้นผิวจะไม่รุนแรงมากไปกว่าตอนก่อนที่จะกระทบพื้นผิว กฎนี้บังคับใช้ในการแสดงผลที่อิงตามกายภาพ แต่ปกติแล้วจะไม่รวมอยู่ในไปป์ไลน์การแสดงผลแบบเดิมที่ใช้ในวิดีโอเกมและแอปบนอุปกรณ์เคลื่อนที่

หากคุณใช้ไปป์ไลน์การแสดงภาพตามตัวจริงที่มีการประมาณแสง HDR สภาพแวดล้อม ให้ตรวจดูว่ามีการใช้วัสดุที่อิงทางกายภาพในวัตถุเสมือนของคุณ

อย่างไรก็ตาม หากไม่ได้ใช้ไปป์ไลน์ที่อิงตามตัวจริง คุณมี 2 ตัวเลือกดังนี้

  • วิธีแก้ปัญหาที่ดีที่สุดสําหรับกรณีนี้คือการย้ายข้อมูลไปยังไปป์ไลน์แบบอิงข้อมูลจริง

  • แต่ถ้าทำไม่ได้ วิธีแก้ปัญหาเบื้องต้นที่ดีคือการคูณค่า Albedo จากวัสดุที่ไม่ได้อาศัยกายภาพด้วยปัจจัยการอนุรักษ์พลังงาน ซึ่งช่วยให้มั่นใจได้ว่าอย่างน้อยโมเดลการแรเงา BRDF สามารถแปลงเป็นแบบจริงได้ แต่ละ BRDF มีปัจจัยที่แตกต่างกัน เช่น ในกรณีของการสะท้อนแบบกระจายจะเท่ากับ 1/Pi