Utiliser la fonctionnalité Depth dans votre application Android AR Foundation

L'API Depth aide l'appareil photo d'un appareil à comprendre la taille et la forme des objets réels d'une scène. Elle utilise l'appareil photo pour créer des images de profondeur, ou cartes de profondeur, et ajoute ainsi un niveau de réalisme de la RA à vos applications. Vous pouvez utiliser les informations fournies par une représentation de profondeur pour faire apparaître avec précision des objets virtuels devant ou derrière des objets du monde réel, offrant ainsi des expériences utilisateur immersives et réalistes.

Les informations de profondeur sont calculées à partir des mouvements et peuvent être combinées à celles d'un capteur matériel de profondeur, tel qu'un capteur de durée de vol, si disponible. Un appareil n'a pas besoin d'un capteur ToF pour être compatible avec l'API Depth.

Prérequis

Assurez-vous de bien maîtriser les concepts fondamentaux de la RA. et comment configurer une session ARCore avant de continuer.

Configurez votre application pour qu'elle soit Depth Required ou Depth Optional (Android uniquement).

Si votre application nécessite la compatibilité avec l'API Depth, soit parce qu'une partie essentielle de l'expérience de RA repose sur la profondeur, soit il n'y a pas de solution de secours pour les parties de l'appli qui utilisent la profondeur, choisir de limiter la distribution de votre application sur le Google Play Store à appareils compatibles avec l'API Depth.

Transformer l'application en Depth Required

Accédez à Edit > Project Settings > XR Plug-in Management > ARCore.

Depth est défini par défaut sur Required.

Transformer l'application en Depth Optional

  1. Accédez à Edit > Project Settings > XR Plug-in Management > ARCore.

  2. Dans le menu déroulant Depth, sélectionnez Optional. pour définir le niveau de profondeur d'une application (facultatif).

Activer la profondeur

Pour économiser des ressources, ARCore n'active pas l'API Depth par défaut. À prendre sur les appareils compatibles, vous devez ajouter manuellement AROcclusionManager à l'objet de jeu AR Camera avec les paramètres Camera et ARCameraBackground. Voir Occlusion automatique dans la documentation Unity pour en savoir plus.

Dans une nouvelle session ARCore, vérifiez si un l'appareil de l'utilisateur est compatible avec l'API Depth et, comme suit:

// 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.
}

Obtenir des représentations de profondeur

Obtenez la dernière représentation de profondeur de l'environnement à partir de 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.
    }
}

Vous pouvez convertir l'image de processeur brute en RawImage. pour plus de flexibilité. Une Pour savoir comment procéder, consultez les exemples ARFoundation d'Unity.

Comprendre les valeurs de profondeur

Point A donné sur la géométrie réelle observée et un point 2D a. représentant le même point dans la représentation de profondeur, la valeur donnée par le paramètre L'API à a est égale à la longueur de CA projetée sur l'axe principal. Également appelée coordonnée Z de A par rapport à la caméra origine C. Lorsque vous utilisez l'API Depth, il est important de comprendre que Les valeurs de profondeur ne correspondent pas à la longueur du rayon CA lui-même, mais à la projection du projet.

Masquer les objets virtuels et visualiser les données de profondeur

Consultez l'article de blog Unity. pour obtenir un aperçu général des données de profondeur et de la façon dont elles peuvent être utilisées pour masquer des images virtuelles. De plus, Unity Exemples ARFoundation pour illustrer l'occlusion d'images virtuelles et la visualisation des données de profondeur.

Vous pouvez effectuer le rendu d'une occlusion à l'aide d'un rendu en deux passes ou d'un rendu par objet en effectuant une passe avant. L'efficacité de chaque approche dépend de la complexité de la scène et d'autres considérations propres à l'application.

Rendu par objet, passage avant

Le rendu avant transmission détermine l'occlusion de chaque pixel de l'objet dans son nuanceur Material. Si les pixels ne sont pas visibles, ils sont rognés, généralement via le mélange alpha, ce qui simule une occlusion sur l'appareil de l'utilisateur.

Rendu en deux passes

Avec le rendu en deux passes, la première passe affiche tout le contenu virtuel dans un tampon intermédiaire. La seconde passe associe la scène virtuelle à l'arrière-plan en fonction de la différence entre la profondeur réelle et la profondeur virtuelle. Cette approche ne nécessite aucun travail supplémentaire du nuanceur spécifique aux objets et produit généralement des résultats d'apparence plus uniformes que la méthode de transmission avant.

Extraire la distance d'une représentation de profondeur

Si vous souhaitez utiliser l'API Depth à d'autres fins que d'occlure des objets virtuels ou de visualiser des données de profondeur, extrayez les informations de la représentation de profondeur.

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;
}

Étapes suivantes

  • Améliorez la précision de la détection avec l'API Raw Depth.
  • Suivez l'atelier ARCore Depth qui présente différentes façons d'accéder aux données de profondeur.