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

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

ข้อมูลความลึกคำนวณจากการเคลื่อนไหวและอาจรวมกับข้อมูลจากเซ็นเซอร์วัดความลึกของฮาร์ดแวร์ เช่น เซ็นเซอร์ตรวจจับช่วงเวลาการบิน (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 เพื่อความยืดหยุ่นที่มากขึ้น CANNOT TRANSLATE ดูตัวอย่างวิธีการได้ในตัวอย่าง ARFoundation ของ Unity

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

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

แยกวัตถุเสมือนออกและแสดงภาพข้อมูลความลึก

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

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

การแสดงผลแบบ Forward Pass ต่อวัตถุ

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

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