홀로그램 안정화 — MRTK2

성능

기본 혼합 현실 플랫폼 및 디바이스가 최상의 결과를 생성하려면 프레임 속도를 수행하는 것이 중요합니다. 대상 프레임 속도(예: 60FPS 또는 90FPS)는 플랫폼 및 디바이스에 따라 달라집니다. 그러나 혼합 현실 응용 프로그램 모임 프레임 속도는 안정적인 홀로그램뿐만 아니라 효율적인 헤드 추적, 손 추적 등을 갖습니다.

환경 추적

안정적인 홀로그램 렌더링은 플랫폼 & 디바이스의 헤드포즈 추적에 크게 의존합니다. Unity는 기본 플랫폼에서 예측하고 제공하는 카메라 포즈의 모든 프레임을 렌더링합니다. 이 추적이 실제 머리 이동을 올바르게 따르지 않으면 홀로그램이 시각적으로 부정확하게 표시됩니다. 이는 사용자가 가상 홀로그램을 실제 세계와 연결할 수 있는 HoloLens 같은 AR 디바이스에 특히 분명하고 중요합니다. 안정적인 헤드 추적에는 성능이 중요하지만 다른 중요한 기능도 있을 수 있습니다. 사용자 환경에 영향을 미치는 환경 요소 유형은 대상 플랫폼 세부 사항에 따라 달라집니다.

Windows Mixed Reality

Windows Mixed Reality 플랫폼은 플랫폼에서 홀로그램을 안정화하기 위한 몇 가지 참조 자료를 제공합니다. 개발자가 사용자의 홀로그램 시각적 환경을 개선하는 데 활용할 수 있는 몇 가지 주요 도구가 있습니다.

깊이 버퍼 공유

Unity 개발자는 애플리케이션의 깊이 버퍼를 플랫폼과 공유할 수 있습니다. 이를 통해 현재 프레임에 홀로그램이 존재하는 경우 플랫폼이 Late-Stage 다시 프로젝션이라고 하는 하드웨어 지원 프로세스를 통해 홀로그램을 안정화하는 데 활용할 수 있는 정보를 제공합니다.

후기 단계 다시 프로젝션

프레임 렌더링이 끝나면 Windows Mixed Reality 플랫폼은 애플리케이션에서 생성한 색 & 깊이 렌더링 대상을 사용하고 마지막 헤드 포즈 예측 이후 약간의 머리 움직임을 고려하여 최종 화면 출력을 변환합니다. 애플리케이션의 게임 루프를 실행하는 데 시간이 걸립니다. 예를 들어 60FPS에서 애플리케이션이 프레임을 렌더링하는 데 최대 16.667ms가 소요된다는 의미입니다. 이 시간은 작은 시간처럼 보일 수 있지만, 사용자의 머리 위치와 방향이 변경되어 렌더링 시 카메라에 대한 새로운 프로젝션 매트릭스가 생성됩니다. 후기 단계 다시 프로젝션은 최종 이미지의 픽셀을 변환하여 이 새로운 관점을 고려합니다.

픽셀당 및 안정화 평면 LSR

Windows Mixed Reality 디바이스에서 실행되는 디바이스 엔드포인트 및 OS 버전에 따라 Late-Stage 다시 프로젝션 알고리즘은 픽셀당 또는 안정화 평면을 통해 수행됩니다.

픽셀별 깊이 기반

픽셀당 깊이 기반 다시 프로젝션에는 깊이 버퍼를 활용하여 픽셀당 이미지 출력을 수정하여 다양한 거리에서 홀로그램을 안정화하는 작업이 포함됩니다. 예를 들어 1m 떨어진 구는 10m 떨어진 기둥 앞에 있을 수 있습니다. 구를 나타내는 픽셀은 사용자가 머리를 약간 기울인 경우 기둥을 나타내는 멀리 떨어진 픽셀과 다른 변환을 갖습니다. 픽셀당 재프로젝션은 보다 정확한 재프로젝션을 위해 모든 픽셀에서 이 거리 차이를 고려합니다.

안정화 평면

플랫폼과 공유할 정확한 깊이 버퍼를 만들 수 없는 경우 다른 형태의 LSR이 안정화 평면을 활용합니다. 장면의 모든 홀로그램은 일부 안정화를 받지만 원하는 평면에 있는 홀로그램은 최대 하드웨어 안정화를 받습니다. 평면의 지점과 표준은 Unity에서 제공하는 HolographicSettings.SetFocusPointForFrameAPI를 통해 플랫폼에 제공할 수 있습니다.

깊이 버퍼 형식

개발을 위해 HoloLens 대상으로 지정하는 경우 24비트 대비 16비트 깊이 버퍼 형식을 활용하는 것이 좋습니다. 깊이 값의 정밀도가 낮아지더라도 성능이 크게 저하될 수 있습니다. 낮은 정밀도를 보완하고 z-fighting을 방지하려면 Unity에서 설정한 1000m 기본값에서 원거리 클립 평면 을 줄이는 것이 좋습니다.

참고

16비트 깊이 형식을 사용하는 경우 Unity가 이 설정에서 스텐실 버퍼를 만들지 않으므로 스텐실 버퍼에 필요한 효과가 작동하지 않습니다. 반대로 24비트 깊이 형식 을 선택하면 일반적으로 엔드포인트 그래픽 플랫폼에 해당하는 경우 8비트 스텐실 버퍼가 생성됩니다.

Unity의 깊이 버퍼 공유

깊이 기반 LSR을 활용하려면 개발자가 수행해야 하는 두 가지 중요한 단계가 있습니다.

  1. 편집>Project 설정>플레이어>XR 설정>Virtual Reality SDK에서깊이 버퍼 공유 사용 >
    1. HoloLens 대상으로 지정하는 경우 16비트 깊이 형식도 선택하는 것이 좋습니다.
  2. 화면에서 색을 렌더링할 때 깊이도 렌더링합니다.

Unity의 불투명 GameObjects는 일반적으로 깊이에 자동으로 기록됩니다. 그러나 투명 & 텍스트 개체는 일반적으로 기본적으로 깊이에 쓰지 않습니다. MRTK 표준 셰이더 또는 텍스트 Mesh Pro 사용하는 경우 쉽게 해결할 수 있습니다.

참고

장면에서 깊이 버퍼에 시각적으로 쓰지 않는 개체를 빠르게 확인하려면 MRTK 구성 프로필의 편집기 설정 아래에 있는 렌더링 깊이 버퍼 유틸리티를 사용할 수 있습니다.

투명한 MRTK 표준 셰이더

MRTK 표준 셰이더를 사용하는 투명한 재질의 경우 검사기 창에서 볼 재질을 선택합니다. 그런 다음 지금 수정 단추를 클릭하여 재질을 깊이로 쓰도록 변환합니다(예: Z-Write On).

이전

Depth Buffer Before Fix MRTK Standard Shader

After

Depth Buffer Fixed MRTK Standard Shader

텍스트 Mesh Pro

Text Mesh Pro 개체의 경우 TMP GameObject를 선택하여 검사기에서 볼 수 있습니다. 재질 구성 요소 아래에서 할당된 재질의 셰이더를 전환하여 MRTK TextMeshPro 셰이더를 사용합니다.

Text Mesh Pro Depth Buffer Fix

사용자 지정 셰이더

사용자 지정 셰이더를 작성하는 경우 Pass 블록 정의의 맨 위에 ZWrite 플래그를 추가하여 깊이 버퍼에 쓰도록 셰이더를 구성합니다.

Shader "Custom/MyShader"
{
    SubShader
    {
        Pass
        {
            ...
            ZWrite On
            ...
        }
    }
}
불투명 지원

위의 메서드가 지정된 시나리오(예: Unity UI 사용)에 대해 작동하지 않는 경우 깊이 버퍼에 다른 개체를 쓸 수 있습니다. 일반적인 예는 장면의 부동 패널에서 Unity UI 텍스트를 사용하는 것입니다. 패널을 불투명하게 만들거나 적어도 깊이에 쓰면 z 값이 서로 너무 가깝기 때문에 패널이 플랫폼에 의해 안정화 & 됩니다.

WorldAnchors(HoloLens)

시각적 안정성을 보장하기 위해 올바른 구성을 충족하는 동시에 홀로그램이 올바른 물리적 위치에서 안정적으로 유지되도록 하는 것이 중요합니다. 물리적 공간의 중요한 위치에 플랫폼을 알리기 위해 개발자는 한 곳에 머물러야 하는 GameObjects에서 WorldAnchors 를 활용할 수 있습니다. WorldAnchor는 해당 개체의 변환을 절대 제어하는 GameObject에 추가된 구성 요소입니다.

HoloLens 같은 디바이스는 지속적으로 환경을 검사하고 학습합니다. 따라서 HoloLens 공간의 이동 & 위치를 추적하므로 예상치가 업데이트되고 Unity 좌표계가 조정됩니다. 예를 들어 GameObject가 시작 시 카메라에서 1m 떨어진 곳에 배치되는 경우 HoloLens 환경을 추적하므로 GameObject가 있는 물리적 지점이 실제로 1.1m 떨어져 있음을 인식할 수 있습니다. 이로 인해 홀로그램이 드리프트될 수 있습니다. GameObject에 WorldAnchor를 적용하면 앵커가 개체의 변환을 제어하여 개체가 올바른 물리적 위치에 유지되도록 할 수 있습니다(즉 런타임에 1m가 아닌 1.1m로 업데이트). 앱 세션 간에 WorldAnchors 를 유지하기 위해 개발자는 WorldAnchorStore 를 사용하여 WorldAnchors를 저장하고 로드할 수 있습니다.

참고

WorldAnchor 구성 요소가 GameObject에 추가되면 해당 GameObject의 변환(즉, transform.position = x)을 수정할 수 없습니다. 개발자는 변환을 편집하려면 WorldAnchor를 제거해야 합니다.

WorldAnchor m_anchor;

public void AddAnchor()
{
    this.m_anchor = this.gameObject.AddComponent<WorldAnchor>();
}

public void RemoveAnchor()
{
    DestroyImmediate(m_anchor);
}

앵커를 수동으로 사용하는 대신 Microsoft World Locking Tools를 확인하세요.

참고 항목