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
Accédez à Edit > Project Settings > XR Plug-in Management > ARCore.
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.