다음을 통해 공유


홀로그램 손떨림 보정 — 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. 프로젝트 설정>편집>플레이어>XR 설정>Virtual Reality SDK에서깊이 버퍼 공유 사용 >
    1. HoloLens를 대상으로 하는 경우 16비트 깊이 형식 도 선택하는 것이 좋습니다.
  2. 화면에서 색을 렌더링할 때 깊이도 렌더링합니다.

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

참고

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

투명한 MRTK Standard 셰이더

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

Before

MRTK Standard 셰이더 수정 전 깊이 버퍼

이후

깊이 버퍼 고정 MRTK Standard 셰이더

Text Mesh Pro

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

Text Mesh Pro 깊이 버퍼 수정

사용자 지정 셰이더

사용자 지정 셰이더를 작성하는 경우 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를 검사.

참고 항목