अपने एआर फ़ाउंडेशन Android ऐप्लिकेशन में गहराई का इस्तेमाल करें

डेप्थ एपीआई की मदद से, डिवाइस के कैमरे को किसी सीन में मौजूद असल ऑब्जेक्ट का साइज़ और आकार समझने में मदद मिलती है. यह कैमरे का इस्तेमाल करके, डीप इमेज या डीप मैप बनाता है. इससे आपके ऐप्लिकेशन में एआर की असल लेयर जुड़ जाती है. डेप्थ इमेज से मिली जानकारी का इस्तेमाल करके, वर्चुअल ऑब्जेक्ट को असल ऑब्जेक्ट के सामने या पीछे सही तरीके से दिखाया जा सकता है. इससे, उपयोगकर्ताओं को बेहतर और ज़्यादा असली अनुभव मिलता है.

गहराई की जानकारी, मोशन से कैलकुलेट की जाती है. साथ ही, अगर उपलब्ध हो, तो इसे हार्डवेयर के गहराई सेंसर, जैसे कि टाइम-ऑफ़-फ़्लाइट (ToF) सेंसर की जानकारी के साथ जोड़ा जा सकता है. Depth API का इस्तेमाल करने के लिए, किसी डिवाइस में ToF सेंसर की ज़रूरत नहीं होती.

ज़रूरी शर्तें

आगे बढ़ने से पहले, पक्का करें कि आपने एआर के बुनियादी कॉन्सेप्ट और ARCore सेशन को कॉन्फ़िगर करने का तरीका समझ लिया हो.

अपने ऐप्लिकेशन को Depth Required या Depth Optional के तौर पर कॉन्फ़िगर करना (सिर्फ़ Android के लिए)

अगर आपके ऐप्लिकेशन को Depth API की ज़रूरत है, तो आपके पास 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 डिफ़ॉल्ट रूप से डेप्थ एपीआई को चालू नहीं करता. जिन डिवाइसों पर यह सुविधा काम करती है उन पर डेप्थ इफ़ेक्ट का फ़ायदा पाने के लिए, आपको Camera और ARCameraBackground कॉम्पोनेंट के साथ एआर कैमरा गेम ऑब्जेक्ट में AROcclusionManager कॉम्पोनेंट को मैन्युअल तरीके से जोड़ना होगा. ज़्यादा जानकारी के लिए, 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 में बदला जा सकता है. ऐसा करने का उदाहरण, Unity के ARFoundation के सैंपल में देखा जा सकता है.

डेप्थ वैल्यू को समझना

असल दुनिया की ज्यामिति में मौजूद बिंदु A और डेप्थ इमेज में उसी बिंदु को दिखाने वाले 2D बिंदु a के लिए, Depth API की दी गई वैल्यू a पर, मुख्य अक्ष पर प्रोजेक्ट किए गए CA की लंबाई के बराबर होती है. इसे कैमरे के ऑरिजिन C के हिसाब से, A का z-कोऑर्डिनेट भी कहा जा सकता है. डेप्थ एपीआई का इस्तेमाल करते समय, यह समझना ज़रूरी है कि डेप्थ वैल्यू, रे CA की लंबाई नहीं होतीं, बल्कि उसका प्रोजेक्शन होती हैं.

वर्चुअल ऑब्जेक्ट को छिपाना और डेप्थ डेटा को विज़ुअलाइज़ करना

डेप्थ डेटा के बारे में खास जानकारी पाने और वर्चुअल इमेज को छिपाने के लिए, Unity का ब्लॉग पोस्ट पढ़ें. इसके अलावा, Unity के ARFoundation के सैंपल में, वर्चुअल इमेज को छिपाने और डेप्थ डेटा को विज़ुअलाइज़ करने का तरीका दिखाया गया है.

दो पास रेंडरिंग या हर ऑब्जेक्ट के लिए फ़ॉरवर्ड-पास रेंडरिंग का इस्तेमाल करके, ऑब्स्क्यूरेशन को रेंडर किया जा सकता है. हर तरीके की परफ़ॉर्मेंस, सीन की जटिलता और ऐप्लिकेशन से जुड़ी अन्य बातों पर निर्भर करती है.

हर ऑब्जेक्ट के लिए फ़ॉरवर्ड-पास रेंडरिंग

हर ऑब्जेक्ट के लिए, फ़ॉरवर्ड-पास रेंडरिंग, ऑब्जेक्ट के हर पिक्सल के ऑब्स्क्यूरेशन को उसके मटीरियल शेडर में तय करती है. अगर पिक्सल नहीं दिखते हैं, तो आम तौर पर अल्फा ब्लेंडिंग की मदद से उन्हें काटा जाता है. इससे, उपयोगकर्ता के डिवाइस पर ऑब्स्क्यूज़न (अवरुद्ध होने की स्थिति) का अनुकरण किया जाता है.

दो पास रेंडरिंग

दो पास रेंडरिंग में, पहला पास पूरे वर्चुअल कॉन्टेंट को इंटरमीडियरी बफ़र में रेंडर करता है. दूसरा पास, असल दुनिया की गहराई और वर्चुअल सीन की गहराई के अंतर के आधार पर, वर्चुअल सीन को बैकग्राउंड में ब्लेंड करता है. इस तरीके में, ऑब्जेक्ट के हिसाब से शेडर को अलग से बनाने की ज़रूरत नहीं होती. आम तौर पर, यह फ़ॉरवर्ड-पास के मुकाबले ज़्यादा एक जैसे नतीजे देता है.

डीप इमेज से दूरी का पता लगाना

डेप्थ एपीआई का इस्तेमाल, वर्चुअल ऑब्जेक्ट को छिपाने या डेप्थ डेटा को विज़ुअलाइज़ करने के अलावा अन्य कामों के लिए करने के लिए, डेप्थ इमेज से जानकारी निकालें.

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 डेप्थ लैब देखें. इसमें डेप्थ डेटा को ऐक्सेस करने के अलग-अलग तरीके दिखाए गए हैं.