استخدام ميزة "العمق" في تطبيق AR Foundation المتوافق مع Android

تساعد Depth API كاميرا الجهاز في فهم حجم وشكل العناصر الحقيقية في المشهد. فهو يستخدم الكاميرا لإنشاء صور معمّقة أو خرائط معمّقة، ما يضيف طبقة من الواقع المعزّز إلى تطبيقاتك. يمكنك استخدام المعلومات المقدَّمة من خلال صورة العمق لجعل العناصر الافتراضية تظهر بدقة أمام أو خلف كائنات العالم الواقعي، ما يُتيح تجارب مستخدم غامرة وواقعية.

يتم احتساب معلومات العمق من الحركة ويمكن دمجها مع معلومات من مستشعر عمق الجهاز، مثل أداة استشعار وقت الطيران، إن توفرت. لا يحتاج الجهاز إلى أداة استشعار ToF للتوافق مع واجهة برمجة التطبيقات Depth API.

المتطلبات الأساسية

قبل المتابعة، تأكد من فهم مفاهيم الواقع المعزّز الأساسية وكيفية ضبط جلسة ARCore.

ضبط تطبيقك على "Depth Required" أو "Depth Optional" (نظام التشغيل Android فقط)

إذا كان تطبيقك يتطلّب دعم Depth API، إما لأنّ جزءًا أساسيًا من تجربة الواقع المعزّز يعتمد على العمق، أو لأنّه لا يوجد إجراء احتياطي مناسب للأجزاء التي تستخدم العمق في التطبيق، يمكنك اختيار قصر توزيع تطبيقك في "متجر Google Play" على الأجهزة المتوافقة مع 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 يدويًا إلى عنصر اللعبة كاميرا الواقع المعزّز مع المكوِّن 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 في الهندسة الواقعية المرصودة والنقطة الثنائية الأبعاد a التي تمثل النقطة نفسها في صورة العمق، فإن القيمة المقدَّمة من خلال واجهة برمجة التطبيقات للعمق في a تساوي طول CA المعروض على المحور الرئيسي. ويمكن الإشارة إلى ذلك أيضًا باسم الإحداثي z لـ A المرتبط بأصل الكاميرا C. عند استخدام Depth API، من المهم أن نفهم أنّ قيم العمق ليست طول شعاع CA نفسه، بل إسقاط له.

حجب العناصر الافتراضية وعرض بيانات عمقها

اطّلِع على مشاركة المدونة الخاصة بـ Unity لإلقاء نظرة عامة عالية المستوى على البيانات المفصّلة وكيفية استخدامها لإخفاء الصور الافتراضية. بالإضافة إلى ذلك، تُظهر عينات ARFoundation في Unity حالات حجب الصور الافتراضية وعرض بيانات العمق بشكل مرئي.

يمكنك عرض التظليل باستخدام العرض على مسارين أو عرض التمرير الأمامي لكل كائن. وتعتمد فعالية كل منهج على مدى تعقيد المشهد والاعتبارات الأخرى الخاصة بالتطبيق.

لكل كائن، عرض التمرير الأمامي

يحدد عرض التمرير الأمامي لكل كائن تراكم كل بكسل من الكائن في أداة تظليل المواد. إذا لم تكن وحدات البكسل مرئية، يتم اقتطاعها، عادةً من خلال مزج ألفا، وبالتالي محاكاة الانسداد على جهاز المستخدم.

العرض على مرّتَين

عند استخدام العرض على مرّتين، تعرض التصريح الأول كل المحتوى الافتراضي في مورد احتياطي وسيط. يمزج الترخيص الثاني بين المشهد الافتراضي والخلفية بناءً على الفرق بين عمق العالم الحقيقي وعمق المشهد الافتراضي. لا يتطلب هذا الأسلوب أي عمل إضافي لأداة التظليل الخاصة بكائن معيّن، ويؤدي بشكل عام إلى نتائج ذات مظهر موحّد أكثر من طريقة التمرير الأمامي.

استخراج المسافة من صورة العمق

لاستخدام 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 الذي يعرض طرقًا مختلفة للوصول إلى بيانات العمق.