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

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

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