AR Foundation Android 앱에서 Depth 사용

Depth API를 사용하면 기기의 카메라가 장면에 있는 실제 객체의 크기와 모양을 이해할 수 있습니다. 카메라를 사용해 깊이 이미지, 즉 깊이 맵을 만들어 앱에 AR 리얼리즘 레이어를 추가합니다. 깊이 이미지에서 제공하는 정보를 사용하여 가상 객체가 실제 객체의 앞이나 뒤에 정확하게 표시되도록 하여 몰입도 높고 현실적인 사용자 환경을 제공할 수 있습니다.

심도 정보는 움직임으로부터 계산되며, 가능한 경우 ToF (Time-of-F) 센서와 같은 하드웨어 깊이 센서의 정보와 결합할 수 있습니다. 기기는 Depth API를 지원하기 위해 ToF 센서가 필요하지 않습니다.

기본 요건

기본 AR 개념을 이해합니다. ARCore 세션을 구성하는 방법을 알아보세요.

앱을 Depth Required 또는 Depth Optional로 구성합니다 (Android만 해당).

앱에 Depth API 지원이 필요한 경우 AR 환경의 핵심 부분이 깊이에 의존하기 때문이거나 앱에서 깊이를 사용하는 부분을 적절하게 대체할 수 있는 방법은 없지만, Google Play 스토어에서의 앱 배포를 제한하려는 경우 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을(를) 선택합니다. 선택사항으로 앱을 Depth로 설정할 수 있습니다.

깊이 사용 설정

리소스를 절약하기 위해 ARCore에서는 기본적으로 Depth API를 사용 설정하지 않습니다. 데리고 가다 이점을 누리기 위해서는 AROcclusionManager 드림 AR 카메라 게임 객체에 Camera 구성 요소를 ARCameraBackground 구성요소 자세한 내용은 자동 오클루전 을 참조하세요.

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

원시 CPU 이미지를 RawImage로 변환할 수 있습니다. 더 큰 유연성을 확보할 수 있습니다 방법 예시는 Unity의 ARFoundation 샘플을 참고하세요.

깊이 값 이해하기

관찰된 실제 도형의 지정된 점 A 및 2D 점 a 깊이 이미지에서 동일한 지점을 나타내며 깊이로 주어진 값 a의 API는 주축에 투영된 CA의 길이와 같습니다. 카메라를 기준으로 한 A의 z 좌표라고도 합니다. 출처 C. Depth API를 사용할 때는 깊이 값은 광선 CA 자체의 길이가 아니라 투영입니다. 있습니다.

가상 객체를 가리고 깊이 데이터 시각화

Unity의 블로그 게시물 확인 심도 데이터에 대한 간략한 개요와 이를 사용하여 오클루드하는 방법을 확인할 수 있습니다. 살펴보겠습니다 또한 Unity의 ARFoundation 샘플 가상 이미지를 가리고 깊이 데이터를 시각화하는 방법을 보여줍니다.

두 패스 렌더링 또는 객체당 정방향 패스 렌더링을 사용하여 오클루전을 렌더링할 수 있습니다. 각 접근 방식의 효율성은 장면의 복잡성과 기타 앱 관련 고려사항에 따라 다릅니다.

객체별, 정방향 패스 렌더링

객체별, 정방향 전달 렌더링은 머티리얼 셰이더에서 객체의 각 픽셀 오클루전을 결정합니다. 픽셀이 보이지 않는 경우 일반적으로 알파 블렌딩을 통해 클립되므로 사용자 기기에서 오클루전이 시뮬레이션됩니다.

이중 패스 렌더링

2 패스 렌더링의 경우 첫 번째 패스는 모든 가상 콘텐츠를 중간 버퍼로 렌더링합니다. 두 번째 패스에서는 실제 깊이와 가상 장면 깊이의 차이에 따라 가상 장면을 배경에 블렌딩합니다. 이 접근 방식에는 객체별 셰이더 작업이 추가로 필요하지 않으며 일반적으로 정방향 전달 메서드보다 더 균일한 결과를 생성합니다.

깊이 이미지에서 거리 추출

가상 객체를 가리거나 깊이 데이터를 시각화하는 것 이외의 목적으로 Depth API를 사용하려면 깊이 이미지에서 정보를 추출하세요.

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 Depth Lab을 확인하세요.