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

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

يتم احتساب معلومات العمق من الحركة، وقد يتم دمجها مع معلومات من جهاز استشعار عمق الجهاز، مثل أداة استشعار مدّة الرحلة (ToF)، في حال توفّرها. لا يحتاج الجهاز إلى استشعار 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.
    }
}

يمكنك تحويل صورة وحدة المعالجة المركزية الأوّلية إلى RawImage لتحقيق مرونة أكبر. يمكنك العثور على مثال على كيفية إجراء ذلك في عيّنات ARFoundation في Unity.

فهم قيم العمق

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