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
นำทางไปยัง 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
เพื่อให้มีความยืดหยุ่นมากขึ้น ดูตัวอย่างวิธีดำเนินการนี้ได้ในตัวอย่าง 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 ซึ่งสาธิตวิธีต่างๆ ในการเข้าถึงข้อมูลความลึก