[Unity / Android] AR Foundation Sample

매일추운날씨·2022년 6월 22일
0

ARCore (Unity)

목록 보기
1/1

지원 기능

Feature Support Per Platform ARCore ARKit
Device tracking
Plane tracking
Point clouds
Anchors
Light estimation
Environment probes
Face tracking
2D Image tracking
Raycast
Pass-through video
Session management
Occlusion
3D Object tracking
Meshing
2D & 3D body tracking
Collaborative participants
Human segmentation

실행 환경

  • Unity : 2021.3.0f1
  • AR Foundation Samples : 4.2 (Unity 에디터 버전은 2021.3.3f1)
  • Galaxy S20 Ultra, Android 12 : 내 테스트

환경 설정

  1. 아래 Github에서 코드를 다운로드 후, 압축을 해제 한다.

  2. Unity Hub를 열고, "열기" → "디스크에서 프로젝트 추가" 버튼을 클릭한 후,
    압축을 푼 프로젝트 폴더(폴더 명은 "arfoundation-samples-4.2" 로 되어있다.)를 선택한다.

  3. Sample 코드는 2021.3.3f1 버전으로 보이게 된다.
    경고창이 떠도 무시하고 에디터를 2021.3.0f1로 선택한 후, 프로젝트를 실행한다.

  4. 프로젝트에 필요한 플러그인은 이미 설치되어 있다. Android로 "Switch Platform"을 한 후, 바로 "Build And Run"을 해도 된다.

    실행 후, 아래 이미지와 같은 화면이 뜨게 된다
    (지원하지 않는 기능은 회색으로 비활성화 되어 있다)

구버전과의 차이


코드 파일 변화

Function ARCore SDK ARFoundation
카메라 이미지 (뒷배경) ARCameraManager.cs - TryAcquireLatestCpuImage
ARBackground.shader
Frame.cs - CameraImage
ARCoreBackground.shader
  • 구버전에서는 ExternApi 형식이었다면, Foundation에서는 각 객체들이 존재 (ARCameraManager, AROcclusionManager)
  • 구버전에서는 GoogleARCore에 있는 Frame 클래스에 있는 변수(DisplayUvCoords에 있는 uv)들을 이용하였다면, Foundation에서는 DisplayMatrix (Matrix4x4)를 이용한다.
  • 가져온 이미지 변환 가능 (XRCpuImage 구조체 이용)

프로젝트 요약

Scene 단위

위 캡쳐 이미지와 관련된 Scene. 각 기능들이 지원되는지 확인하고, 버튼들을 활성화 시킨다.

  • Scripts
    • UX
      • ARSceneSelectUI.cs
      • CheckAvailableFeatures.cs


SimpleAR

Point cloud Visualization 및 Plane Detection을 테스트 할 수 있다. 인식된 평면 위를 터치하면 큐브를 놓을 수 있다. (ARRaycastManager를 사용한다.)

  • Scripts
    • PlaceOnPlane.cs
SimpleAR 실행 예시
이미지 중간에 보이는 주황색 점이 PointCloud 이고, 노란색 투명한 영역이 평면으로 인식한 지점이다.
평면으로 인식된 지점 위에 손가락 터치로 큐브를 놓을 수 있다.


Check Support

AR 기능 지원 체크. 소프트웨어가 없다면 설치 기능을 제공.

  • Scripts
    • SupportChecker.cs


Light Estimation

Basic Light Estimation

현재 카메라 프레임에 대한 빛 검증. 기본적으로 "Ambient Intensity", "Ambient Color" 값을 보여준다.
"AR Camera"의 컴포넌트 추가되어 있는 "AR Camera Manager"의 "Light Estimation" 부분을 살펴보면, "Ambient Intensity", "Ambient Color" 부분이 체크되어 있음을 확인 할 수 있다.

  • Scenes
    • FaceDirectionManager.cs
    • Rotator.cs
  • Scripts
    • BasicLightEstimation.cs
    • BasicLightEstimationUI.cs

HDR Light Estimation

Basic Light Estimation 보다 기능이 더 추가되었다. "Ambient Intensity", "Ambient Color" 이외에 "Main Light Direction", "Main Light Intensity Lumens", "Main Light Color", and "Spherical Harmonics" 항목이 추가되었다. 비 지원 항목은 "Unavailable"이 뜬다. (일단 기본 값으로 "AR Camera Manager"의 "Light Estimation"은 "Main Light Direction", "Main Light Intensity", "Ambient Spherical Harmonics" 만 체크되어 있다.)
"AR Camera Manager"의 "Face Direction"이 Android의 경우 "World", iOS의 경우 "User"로 설정된다. (단, iOS의 경우 Face tracking이 지원되는 장치만 사용할 수 있다.)

  • Scenes
    • FaceDirectionManager.cs
    • Rotator.cs
  • Scripts
    • HDRLightEstimation.cs
    • HDRLightEstimationUI.cs



Anchors

스크린을 클릭하면 Raycast 결과를 이용하여 Anchor를 생성한다.
생성되는 Anchor는 두 종류 이다.
1. 평면 부분 클릭시, 평면과 연결된 Anchor 생성. "Create anchor attachment" (하단 사진)
1. 점 부분 클릭시, 일반 Anchor 생성. "Create regular anchor"

  • Scripts
    • AnchorCreator.cs
    • Logger.cs



Scale

평면으로 인식된 지점 위에 메시를 이동하거나 배치할 수 있다. 그리고 스크롤 바를 이용하여 메시를 Scaling 또는 Rotation을 할 수 있다. Scene 전체의 Scale 및 Rotation을 제어하는 것은 다른 곳에 영향을 줄 수 있는 리스크가 있기 때문에 "AR Session Origin"의 Scale, Rotation을 제어한다.

Scale : (0.1 ~ 200) 스크롤 오른쪽 조작시 메시가 작아진다.
Rotation : (0 ~ 360) 스크롤 오른쪽 조작시 시계 방향으로 메시가 회전한다.


  • Scripts
    • MakeAppearOnPlane.cs
    • ScaleController.cs
    • RotationController.cs


CPU Images

지원 가능한 카메라 구성이 왼쪽 하단에 드롭다운 메뉴 형식으로 제공된다. 휴대전화 기종에 따라서 DropDown 메뉴에 보이는 텍스쳐 사이즈와 "depth senesor" 기능 지원 여부가 다르다. UI 상 위치는 아래 표와 같다

RawCameraImage
왼쪽 상단 (이미지 정보 텍스트의 왼쪽 부분)
(공란)
RawEnvDepthImageRawEnvDepthConfidenceImage
RawHumanDepthImage (iOS 13 이상)RawHumanStencilImage (iOS 13 이상)


  • Scripts
    • CameraConfigController.cs
      DropDown 메뉴에 관련 코드로 단말기의 카메라 기능에 따라 목록이 다르게 보일 수 있다. 기본적으로 Background image(배경)는 640x480, 1280x720, 1920x1080 사이즈를 가진다(목록 3개).
      기본적인 depth image 사이즈는 160x90 인데, depth sensor가 지원되면 640x360 사이즈도도 가져올 수 있이며, DropDown 메뉴 목록 명칭 뒷부분에 "depth sensor" 접미어가 추가로 붙는다 (이 경우 Dropdown 목록이 6개가 된다).

      사이즈비고
      640x480 at 30 Hz depth sensorDepth sensor 지원 기종만 가능
      1280x720 at 30 Hz depth sensorDepth sensor 지원 기종만 가능
      1920x1080 at 30 Hz depth sensorDepth sensor 지원 기종만 가능
      640x480 at 30 Hz
      1280x720 at 30 Hz
      1920x1080 at 30 Hz

    • CpuImageSample.cs
Depth SensorNormal

  • (추가) 위 샘플은 한창 동작 중인 Scene에서 CameraConfiguration을 바꾸는 구문이다. "런타임 중에 카메라 구성"에 있는 방법을 이용하면 앱을 실행하자마자 CameraConfiguration을 변경할 수 있다.
//ARCoreExtensions 클래스 내부/// <summary>
/// The callback event that allows a camera configuration to be selected from
/// a list of valid configurations.
/// The callback should be registered before the ARCore session is enabled
/// (e.g. Unity's Awake() method) to ensure it is triggered on the first
/// frame update.
/// </summary>
[HideInInspector]
public OnChooseXRCameraConfigurationEvent OnChooseXRCameraConfiguration;

/// <summary>
/// Selects a camera configuration for the ARCore session to use.
/// </summary>
/// <param name="supportedConfigurations">A list of supported camera configurations.
/// The size is dependent on <c><see cref="CameraConfigFilter"/></c> settings.
/// The GPU texture resolutions are the same in all configs.
/// Currently, most devices provide GPU texture resolution of 1920 x 1080, but devices
/// might provide higher or lower resolution textures, depending on device capabilities.
/// The CPU image resolutions returned are VGA, 720p, and a resolution matching
/// the GPU texture, typically the native resolution of the device.</param>
/// <returns>The index of the camera configuration in <c>supportedConfigurations</c> to be
/// used for the ARCore session. If the return value is not a valid index
/// (e.g. the value -1), then no camera configuration will be set and the ARCore session
/// will use the previously selected camera configuration or a default configuration
/// if no previous selection exists.</returns>
public delegate int OnChooseXRCameraConfigurationEvent(List<XRCameraConfiguration> supportedConfigurations);public void Update()
{// Update camera config filter
    if (CameraConfigFilter != null && !CameraConfigFilter.Equals(_cachedFilter))
    {
        _cachedFilter = ScriptableObject.CreateInstance<ARCoreExtensionsCameraConfigFilter>();
        _cachedFilter.CopyFrom(CameraConfigFilter);

        // Extensions will attempt to select the camera config based on the filter
        // if it's in use, otherwise, relies on AR Foundation's default behavior.
        SelectCameraConfig();
    }}private void SelectCameraConfig()
{
    if (CameraManager == null)
    {
        return;
    }

    using (var configurations = CameraManager.GetConfigurations(Allocator.Temp))
    {
        if (configurations.Length == 0)
        {
            Debug.LogWarning(
                "Unable to choose a custom camera configuration " +
                "because none are available.");
            return;
        }

        int configIndex = 0;
        if (OnChooseXRCameraConfiguration != null)
        {
            configIndex = OnChooseXRCameraConfiguration(configurations.ToList());
        }

        if (configIndex < 0 || configIndex >= configurations.Length)
        {
            Debug.LogWarning(
                "Failed to find a valid config index with " +
                "the custom selection function.");
            return;
        }

        CameraManager.currentConfiguration = configurations[configIndex];
    }
}

…
…
…

// [런타임 중에 카메라 구성](https://developers.google.com/ar/develop/unity-arf/camera-configs?hl=ko#configure_the_camera_during_runtime) 링크 내부 내용

// 아무 MonoBehavior를 상속 받은 클래스 내부

// 여기에 ARCoreExtensions 스크립트를 사용한 GameObject를 연결
[SerializeField]
private ARCoreExtensions arCoreExtensions;// Unity's Awake() method
public void Awake()
{// If the return value is not a valid index (ex. the value if -1),
    // then no camera configuration will be set. If no previous selection exists, 
    // the ARCore session will use the previously selected camera configuration 
    // or a default configuration.
    arcoreExtensions.OnChooseXRCameraConfiguration = SelectCameraConfiguration;}

// A custom camera configuration selection function
int SelectCameraConfiguration(List<XRCameraConfiguration> supportedConfigurations)
{
    int index = 0;

    // Use custom logic here to choose the desired configuration from supportedConfigurations.
    // 여기 부분에 Sample에서 제공하는 소스코드를 사용하도 된다.

    return index;
}

Plane Detection

Feathered Planes

기본적인 평면 감지 기능. 평면 가장자리 부분에서는 Fade out 처리. AR Package에서 제공하는 코드 이용.

실행 예시

Plane Classification

Android에서는 지원하지 않음

Toggle Plane Detection

평면 감지 기능 On/Off. 평면 GameObject visible (Activated) 상태와 invisible (Deactivated) 상태간 전환.

  • Scripts
    • PlaneDetectionController.cs
EnableDisable


Plane Occlusion

기본적인 평면 감지 기능과 같지만, 평면 부분의 머티리얼을 Occlustion shader로 처리되어있다. 평면의 테두리는 검은 색으로 표시되어 있다. 평면 부분을 클릭하면 하얀색 큐브가 만들어진다. 평면에 접촉되는 부분은 잘리거나 가려진 것 처럼 보인다. (평면으로 인식되지 않은 부분에 대해서는 큐브에 반응이 없다.)

  • Scripts
    • PlaneOnPlane.cs



Environment Probes (Env Probes)

일정 공간을 은색 구슬로 배치한 것 같은 모습.
실제 환경에 Reflective material이 적용된 구 모양의 3D 텍스쳐를 여러개 배치한 것이다.
처음 시작시 몇몇 구의 표면의 색상은 검은색이지만, 곧 주변 환경이 반영되어 나타나게 된다.



Image Tracking

Basic Image Tracking

Image Tracking With Multiple Prefabs


Face Tracking

Face Regions

Face Mesh

Face Pose

Rear Camera

하단의 4개 항목은 지원 안함

Blend Shapes

Eye Lasers

Eye Poses

Fixation Point



Depth

Simple Occlusion

스크린을 터치하면 해당 지점을 기준으로 빨간색 구가 생성되어 발사된다. (사격하는 느낌)

Depth Images

오른쪽 상단에 각각 다른 메소드에 의한 raw texture depth image 정보를 띄워준다.

  • Environment depth
  • Human stencil (iOS 단말)
  • Human depth (iOS 단말)

  • Scripts
    • DisplayDepthImage.cs
    • CameraConfigController.cs


Point Cloud



Interaction

평면 위에 지점을 클릭하여 여러개의 큐브를 배치할 수 있다. 배치된 큐브를 선택한 후, 손가락 제스쳐를 사용하여 이동, 회전, 크기 조정이 가능하다.

  • Packages
    • XR Interaction Toolkit



Input System



Config Chooser

후면 카메라전면 카메라 (셀프)

0개의 댓글