ใช้ความลึกในแอป AR Foundation สำหรับ Android

Depth API ช่วยให้กล้องของอุปกรณ์เข้าใจขนาดและรูปร่างของวัตถุจริงในฉาก โดยจะใช้กล้องเพื่อสร้างรูปภาพความลึกหรือแผนที่ความลึก ซึ่งจะเพิ่มชั้นความสมจริงของ AR ในแอป คุณสามารถใช้ข้อมูลที่ได้จากรูปภาพความลึกเพื่อให้วัตถุเสมือนจริงปรากฏขึ้นอย่างถูกต้องด้านหน้าหรือด้านหลังวัตถุในชีวิตจริง ซึ่งช่วยให้ผู้ใช้ได้รับประสบการณ์ที่สมจริงและน่าประทับใจ

ระบบจะคำนวณข้อมูลความลึกจากการเคลื่อนไหวและอาจรวมเข้ากับข้อมูลจากเซ็นเซอร์ความลึกของฮาร์ดแวร์ เช่น เซ็นเซอร์ Time-of-Flight (ToF) หากมี อุปกรณ์ไม่จำเป็นต้องมีเซ็นเซอร์ ToF เพื่อรองรับ Depth API

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

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

กําหนดค่าแอปเป็น Depth Required หรือ Depth Optional (Android เท่านั้น)

หากแอปของคุณต้องใช้การรองรับ Depth API เนื่องจากส่วนสำคัญของประสบการณ์ AR อาศัยข้อมูลเชิงลึก หรือเนื่องจากไม่มีทางเลือกสำรองสำหรับส่วนต่างๆ ของแอปที่ใช้ข้อมูลเชิงลึก คุณอาจเลือกจำกัดการเผยแพร่แอปใน Google Play Store ไว้สำหรับอุปกรณ์ที่รองรับ Depth API

สร้างแอป Depth Required

นำทางไปยัง Edit > Project Settings > XR Plug-in Management > ARCore

Depth จะตั้งค่าเป็น Required โดยค่าเริ่มต้น

สร้างแอป Depth Optional

  1. นำทางไปยัง Edit > Project Settings > XR Plug-in Management > ARCore

  2. จากเมนูแบบเลื่อนลง Depth ให้เลือก Optional เพื่อตั้งค่าแอปเป็น "ไม่บังคับ"

เปิดใช้ความลึก

ARCore จะไม่เปิดใช้ Depth API โดยค่าเริ่มต้นเพื่อประหยัดทรัพยากร หากต้องการใช้ประโยชน์จากภาพความลึกในอุปกรณ์ที่รองรับ คุณต้องเพิ่มคอมโพเนนต์ AROcclusionManager ลงในออบเจ็กต์เกม AR Camera ด้วยคอมโพเนนต์ Camera และ ARCameraBackground ด้วยตนเอง ดูข้อมูลเพิ่มเติมเกี่ยวกับการบดบังอัตโนมัติในเอกสารประกอบของ Unity

ในเซสชัน ARCore ใหม่ ให้ตรวจสอบว่าอุปกรณ์ของผู้ใช้รองรับความลึกและ Depth API หรือไม่ ดังนี้

// Reference to AROcclusionManager that should be added to the AR Camera
// game object that contains the Camera and ARCameraBackground components.
var occlusionManager = …

// Check whether the user's device supports the Depth API.
if (occlusionManager.descriptor?.supportsEnvironmentDepthImage)
{
    // If depth mode is available on the user's device, perform
    // the steps you want here.
}

รับภาพความลึก

รับภาพความลึกของสภาพแวดล้อมล่าสุดจาก AROcclusionManager

// Reference to AROcclusionManager that should be added to the AR Camera
// game object that contains the Camera and ARCameraBackground components.
var occlusionManager = …

if (occlusionManager.TryAcquireEnvironmentDepthCpuImage(out XRCpuImage image))
{
    using (image)
    {
        // Use the texture.
    }
}

คุณสามารถแปลงรูปภาพ CPU ดิบเป็น RawImage เพื่อให้มีความยืดหยุ่นมากขึ้น ดูตัวอย่างวิธีดำเนินการนี้ได้ในตัวอย่าง ARFoundation ของ Unity

ทําความเข้าใจค่าความลึก

เมื่อพิจารณาจุด A ในเรขาคณิตในโลกแห่งความเป็นจริงที่สังเกตได้และจุด 2 มิติ a ที่แสดงจุดเดียวกันในภาพความลึก ค่าที่ Depth API ระบุที่ a จะเท่ากับความยาวของ CA ที่โปรเจ็กต์ไปยังแกนหลัก หรือจะเรียกว่าพิกัด z ของ A เทียบกับจุดเริ่มต้น C ของกล้องก็ได้ เมื่อใช้ Depth API สิ่งสำคัญคือต้องเข้าใจว่าค่าความลึกไม่ใช่ความยาวของรังสี CA แต่เป็นการฉายของรังสี

บดบังวัตถุเสมือนและแสดงข้อมูลเชิงลึกเกี่ยวกับความลึก

อ่านบล็อกโพสต์ของ Unity เพื่อดูภาพรวมระดับสูงของข้อมูลเชิงลึกและวิธีใช้ข้อมูลดังกล่าวเพื่อบดบังภาพเสมือน นอกจากนี้ ตัวอย่าง ARFoundation ของ Unity ยังแสดงภาพเสมือนที่บดบังและการแสดงข้อมูลเชิงลึก

คุณสามารถเรนเดอร์การบดบังได้โดยใช้การเรนเดอร์ 2 ผ่านหรือการเรนเดอร์แบบส่งต่อต่อวัตถุ ประสิทธิภาพของแต่ละแนวทางขึ้นอยู่กับความซับซ้อนของฉากและการพิจารณาอื่นๆ ที่เจาะจงแอป

การแสดงผลแบบส่งต่อต่อออบเจ็กต์

การแสดงผลแบบส่งต่อสำหรับแต่ละออบเจ็กต์จะกำหนดการบดบังของพิกเซลแต่ละพิกเซลของออบเจ็กต์ในโปรแกรมเปลี่ยนสีของวัสดุ หากไม่เห็นพิกเซล ระบบจะตัดพิกเซลออก โดยปกติแล้วจะใช้การผสมอัลฟ่าเพื่อจำลองการบดบังในอุปกรณ์ของผู้ใช้

การแสดงผลแบบ 2 ผ่าน

เมื่อใช้การแสดงผลแบบ 2 ผ่าน การแสดงผลครั้งแรกจะแสดงผลเนื้อหาเสมือนจริงทั้งหมดลงในบัฟเฟอร์สื่อกลาง ผ่านที่ 2 จะผสานฉากเสมือนเข้ากับพื้นหลังตามความแตกต่างระหว่างความลึกในชีวิตจริงกับความลึกของฉากเสมือน วิธีการนี้ไม่จำเป็นต้องใช้การปรับแต่งเพิ่มเติมสำหรับชิเดอร์เฉพาะวัตถุ และโดยทั่วไปจะให้ผลลัพธ์ที่ดูสม่ำเสมอกว่าวิธีการส่งต่อ

ดึงข้อมูลระยะทางจากรูปภาพความลึก

หากต้องการใช้ Depth API เพื่อวัตถุประสงค์อื่นนอกเหนือจากการบดบังวัตถุเสมือนจริงหรือการแสดงภาพข้อมูลเชิงลึก ให้ดึงข้อมูลจากรูปภาพความลึก

Texture2D _depthTexture;
short[] _depthArray;

void UpdateEnvironmentDepthImage()
{
  if (_occlusionManager &&
        _occlusionManager.TryAcquireEnvironmentDepthCpuImage(out XRCpuImage image))
    {
        using (image)
        {
            UpdateRawImage(ref _depthTexture, image, TextureFormat.R16);
            _depthWidth = image.width;
            _depthHeight = image.height;
        }
    }
  var byteBuffer = _depthTexture.GetRawTextureData();
  Buffer.BlockCopy(byteBuffer, 0, _depthArray, 0, byteBuffer.Length);
}

// Obtain the depth value in meters at a normalized screen point.
public static float GetDepthFromUV(Vector2 uv, short[] depthArray)
{
    int depthX = (int)(uv.x * (DepthWidth - 1));
    int depthY = (int)(uv.y * (DepthHeight - 1));

    return GetDepthFromXY(depthX, depthY, depthArray);
}

// Obtain the depth value in meters at the specified x, y location.
public static float GetDepthFromXY(int x, int y, short[] depthArray)
{
    if (!Initialized)
    {
        return InvalidDepthValue;
    }

    if (x >= DepthWidth || x < 0 || y >= DepthHeight || y < 0)
    {
        return InvalidDepthValue;
    }

    var depthIndex = (y * DepthWidth) + x;
    var depthInShort = depthArray[depthIndex];
    var depthInMeters = depthInShort * MillimeterToMeter;
    return depthInMeters;
}

สิ่งที่จะเกิดขึ้นหลังจากนี้

  • เปิดใช้การตรวจจับที่แม่นยำยิ่งขึ้นด้วย Raw Depth API
  • โปรดดูARCore Depth Lab ซึ่งสาธิตวิธีต่างๆ ในการเข้าถึงข้อมูลเชิงลึก