Interfejs Depth API pomaga kamerze urządzenia rozpoznawać rozmiar i kształt rzeczywistych obiektów w scenie. Korzysta ona z kamery do tworzenia obrazów głębi, czyli map głębi, dzięki czemu dodaje do Twoich aplikacji warstwę realizmu AR. Korzystając z informacji zawartych w zdjęciu głębi, możesz sprawić, że obiekty wirtualne będą pojawiać się dokładnie przed lub za obiektami rzeczywistymi, co zapewni użytkownikom realistyczne wrażenia.
Informacje o głębi są obliczane na podstawie ruchu i można je łączyć z informacjami z czujnika głębi sprzętowej, takiego jak czujnik czasu przelotu (ToF), jeśli jest dostępny. Aby obsługiwać Depth API, urządzenie nie musi mieć czujnika ToF.
Wymagania wstępne
Zanim przejdziesz dalej, zapoznaj się z podstawowymi zagadnieniami dotyczącymi rozszerzonej rzeczywistości oraz dowiedz się, jak skonfigurować sesję ARCore.
Skonfiguruj aplikację jako Depth Required lub Depth Optional (tylko na urządzeniach z Androidem)
Jeśli Twoja aplikacja wymaga obsługi interfejsu Depth API, ponieważ główna część funkcji AR opiera się na głębi lub ponieważ nie ma łagodnego rozwiązania zastępczego dla części aplikacji, które wykorzystują głębię, możesz ograniczyć dystrybucję aplikacji w Sklepie Google Play do urządzeń obsługujących Depth API.
Utwórz aplikację Depth Required
Wejdź na Edit > Project Settings > XR Plug-in Management > ARCore.
Domyślnie Depth ma wartość Required.
Utwórz aplikację Depth Optional
Wejdź na Edit > Project Settings > XR Plug-in Management > ARCore.
Aby ustawić opcję Depth na opcjonalną, w menu Depth wybierz Optional.
Włączanie opcji Głębokość
Aby oszczędzać zasoby, ARCore nie włącza domyślnie Depth API. Aby korzystać z głębi na obsługiwanych urządzeniach, musisz ręcznie dodać komponent AROcclusionManager
do obiektu gry AR Camera za pomocą komponentu Camera
i ARCameraBackground
. Więcej informacji znajdziesz w dokumentacji Unity na temat automatycznego zaciemnienia.
W nowej sesji ARCore sprawdź, czy urządzenie użytkownika obsługuje głębię i interfejs 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.
}
Pobieranie obrazów głębi
Pobierz najnowszy obraz głębi środowiska z 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.
}
}
Aby uzyskać większą elastyczność, możesz przekonwertować obraz w formacie RAW na RawImage
. Przykład tego, jak to zrobić, znajdziesz w próbkach ARFoundation w Unity.
Interpretowanie wartości głębokości
Dla punktu A
w obserwowanej geometrii świata rzeczywistego i punktu 2D a
reprezentującego ten sam punkt na obrazie głębi wartość zwracana przez Depth API w punkcie a
jest równa długości wektora CA
, który jest rzutowany na oś główną.
Można ją też nazwać współrzędną z elementu A
względem punktu początkowego kamery C
. Podczas pracy z interfejsem Depth API należy pamiętać, że wartości głębi nie są długością promienia CA
, ale jego projekcją.
zasłonięcie wirtualnych obiektów i wizualizacja danych głębi;
Aby uzyskać ogólny przegląd danych o głębi i tego, jak można ich używać do zasłaniania obrazów wirtualnych, przeczytaj ten artykuł na blogu Unity. Dodatkowo w przykładach kodu ARFoundation w Unity można znaleźć przykłady zasłonięcia wirtualnych obrazów i wizualizacji danych głębi.
Możesz renderować zasłonięcie, korzystając z renderowania w 2 przelotach lub renderowania do przodu dla poszczególnych obiektów. Skuteczność każdego podejścia zależy od złożoności sceny i innych czynników związanych z aplikacją.
Rendering w przód dla poszczególnych obiektów
Rendering w przód na poziomie obiektu określa zasłonięcie każdego piksela obiektu w jego shaderze materiału. Jeśli piksele są niewidoczne, są one przycinane, zwykle przez mieszanie alfa, co symuluje zasłonięcie na urządzeniu użytkownika.
Renderowanie w 2 przelotach
W przypadku renderowania w 2 przelotach pierwszy przelot renderuje wszystkie wirtualne treści do pośredniego bufora. Drugi przejazd łączy wirtualną scenę z tłem na podstawie różnicy między rzeczywistą głębią a głębią wirtualnej sceny. To podejście nie wymaga dodatkowej pracy nad shaderem dla poszczególnych obiektów i zwykle daje bardziej jednolite wyniki niż metoda bezpośredniego renderowania.
Wyodrębnianie odległości z obrazu głębi
Aby używać Depth API do celów innych niż zasłonięcie obiektów wirtualnych lub wizualizacja danych głębi, wyodrębnij informacje z obrazu głębi.
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;
}
Co dalej?
- Umożliwia dokładniejsze wykrywanie za pomocą interfejsu Raw Depth API.
- Zapoznaj się z ARCore Depth Lab, w którym znajdziesz różne sposoby uzyskiwania dostępu do danych głębi.