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
นำทางไปยัง Edit > Project Settings > XR Plug-in Management > ARCore
จากเมนูแบบเลื่อนลง 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 ซึ่งสาธิตวิธีต่างๆ ในการเข้าถึงข้อมูลความลึก