ใช้ความลึกในแอป 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 ผ่าน การแสดงผลครั้งแรกจะแสดงผลเนื้อหาเสมือนจริงทั้งหมดลงในบัฟเฟอร์สื่อกลาง ส่วนที่สองจะผสานฉากเสมือนจริงลงบนพื้นหลัง โดยอิงตามความแตกต่างระหว่างความลึกในโลกแห่งความจริงกับความลึกของฉากเสมือนจริง วิธีนี้ไม่จำเป็นต้องใช้ตัวปรับแสงเงาเฉพาะออบเจ็กต์เพิ่มเติม และโดยทั่วไปแล้วจะให้ผลลัพธ์ที่เป็นแบบเดียวกันมากกว่าวิธีส่งต่อผ่าน

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

หากต้องการใช้ 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 ซึ่งสาธิตวิธีต่างๆ ในการเข้าถึงข้อมูลความลึก