L'API Depth aide la caméra 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 des cartes de profondeur, ce qui ajoute une couche de réalisme RA à vos applications. Vous pouvez utiliser les informations fournies par une image de profondeur pour faire apparaître avec précision des objets virtuels, devant ou derrière des objets réels, ce qui permet de proposer des expériences utilisateur immersives et réalistes.
Les informations de profondeur sont calculées à partir du mouvement et peuvent être combinées aux informations d'un capteur de profondeur matériel, tel qu'un capteur de temps de vol (ToF), le cas échéant. Un appareil n'a pas besoin d'un capteur ToF pour être compatible avec l'API Depth.
Prérequis
Avant de continuer, assurez-vous de bien comprendre les concepts fondamentaux de la RA et de savoir configurer une session ARCore.
Configurer votre application en tant que Depth Required ou Depth Optional (Android uniquement)
Si votre application nécessite la prise en charge de l'API Depth, soit parce qu'une partie essentielle de l'expérience AR repose sur la profondeur, soit parce qu'il n'existe pas de solution de remplacement appropriée pour les parties de l'application qui utilisent la profondeur, vous pouvez choisir de limiter la distribution de votre application sur le Google Play Store aux appareils compatibles avec l'API Depth.
Rendre votre application Depth Required
Accédez à Edit > Project Settings > XR Plug-in Management > ARCore.
Depth est défini par défaut sur Required.
Rendre votre application Depth Optional
Accédez à Edit > Project Settings > XR Plug-in Management > ARCore.
Dans le menu déroulant Depth, sélectionnez Optional pour définir une application sur "Profondeur facultative".
Activer la profondeur
Pour économiser des ressources, ARCore n'active pas l'API Depth par défaut. Pour exploiter la profondeur sur les appareils compatibles, vous devez ajouter manuellement le composant AROcclusionManager
à l'objet de jeu Caméra RA avec les composants Camera
et ARCameraBackground
. Pour en savoir plus, consultez la section Occlusion automatique dans la documentation Unity.
Dans une nouvelle session ARCore, vérifiez si l'appareil de l'utilisateur est compatible avec la profondeur et l'API Depth, 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.
}
Acquérir des images de profondeur
Obtenez la dernière image 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 du processeur brut en RawImage
pour plus de flexibilité. Vous trouverez un exemple de procédure dans les exemples ARFoundation d'Unity.
Comprendre les valeurs de profondeur
Étant donné le point A
sur la géométrie du monde réel observée et un point 2D a
représentant le même point dans l'image de profondeur, la valeur donnée par l'API Depth à a
est égale à la longueur de CA
projetée sur l'axe principal.
On peut également parler de la coordonnée z de A
par rapport à l'origine de la caméra C
. Lorsque vous travaillez avec 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 à sa projection.
Masquer des objets virtuels et visualiser des données de profondeur
Consultez l'article de blog d'Unity pour obtenir une présentation générale des données de profondeur et de la façon dont elles peuvent être utilisées pour masquer des images virtuelles. De plus, les échantillons ARFoundation d'Unity montrent comment masquer des images virtuelles et visualiser des données de profondeur.
Vous pouvez effectuer le rendu de l'occlusion à l'aide d'un rendu en deux passes ou d'un rendu par objet, en mode de rendu direct. 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, avec pass avant
Le rendu par objet en pass avant détermine l'occlusion de chaque pixel de l'objet dans son nuanceur de matière. Si les pixels ne sont pas visibles, ils sont rognés, généralement via un mélange alpha, ce qui simule l'occlusion sur l'appareil de l'utilisateur.
Rendu en deux passes
Avec le rendu en deux passes, la première passe effectue le rendu de l'intégralité du contenu virtuel dans un tampon intermédiaire. La deuxième passe mélange la scène virtuelle à l'arrière-plan en fonction de la différence entre la profondeur réelle et la profondeur de la scène virtuelle. Cette approche ne nécessite aucune tâche de nuanceur spécifique à l'objet supplémentaire et produit généralement des résultats plus uniformes que la méthode de pass avant.
Extraire la distance à partir d'une image de profondeur
Pour utiliser l'API Depth à d'autres fins que l'occlusion d'objets virtuels ou la visualisation de données de profondeur, extrayez des informations de l'image 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.
- Découvrez l'atelier de profondeur ARCore, qui présente différentes façons d'accéder aux données de profondeur.