Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
XR 설정하기
Godot의 XR 시스템 소개
Godot는 사용자가 서로 다른 XR 플랫폼들의 특수한 사항을 신경쓰지 않게 하기 위해서 추상화된 모듈화 XR 시스템을 제공합니다. 그 핵심은 :ref:`XRServer <class_xrserver>`로 XR 시스템과의 일원화된 인터페이스이며 사용자는 여기서 XR 시스템의 인터페이스를 찾을 수 있고, 컴포넌트와 상호작용할 수 있습니다.
지원하는 각각의 XR 플랫폼은 XRInterface <class_xrinterface>`로 구현되어 있습니다. 지원하는 인터페이스는 :ref:`XRServer <class_xrserver>`에 등록되고 ``find_interface` 메서드를 사용해 쿼리할 수 있습니다. 의도한 인터페이스를 찾았다면 ``initialize``를 호출하여 초기화 할 수 있습니다.
경고
인터페이스가 등록되었다는 것은 단순히 그 인터페이스가 사용 가능하다는 의미이며, 만일 호스트 시스템에서 그 인터페이스를 지원하지 않는다면 초기화가 실패하고 ``false``를 반환합니다. 이런 일이 발생하는 원인은 다양하며, 안타깝게도 플랫폼별로 그 이유가 다를 수 있습니다. 사용자가 필요한 소프트웨어를 설치하지 않아서 일 수도 있고, 헤드셋을 연결하지 않았기 때문일 수도 있습니다. 여러분은 개발자로써, 인터페이스의 초기화가 실패할 경우 그에 따라 적절히 반응하도록 개발하셔야 합니다.
XR로의 출력은 특수한 요구 사항을 만족해야 하는데, 특히 양 눈에 다른 이미지를 보여줘야 하는 HMD 장비와 같은 경우 Godot의 XRServer는 렌더링 시스템의 다양한 기능을 오버라이드 하게 됩니다. 독립형(stand-alone) 장치의 경우 이는 XRInterface가 최종 출력을 책임진다는 뜻이고 Godot의 사용자 출력 시스템은 비활성화됩니다. 데스크톱 XR 장치의 경우 두 번째 화면처럼 동작하므로 XR 출력을 위한 별도의 Viewport가 이를 처리하도록 할 수 있습니다. 이런 경우 주요 Godot 창은 다른 컨텐츠를 출력할 수도 있습니다.
참고
하나의 인터페이스로만 XR 장치의 출력을 관리할 수 있다는 점에 유의하세요. 이를 주(primary) 인터페이스라 하고 기본적으로 가장 먼저 초기화된 인터페이스가 됩니다. Godot는 현재 하나의 헤드셋만 지원하도록 구현되어 있습니다. 아주 드물게 두 번째 인터페이스가 있는 경우가 있는데 예를 들어 3DOF만을 지원하는 장치에 추가적인 트래킹을 더하는 경우가 그 예시입니다.
거의 대부분의 XR 응용 프로그램에서 사용하는, XR을 위한 노드 타입이 세 가지 있습니다:
XROrigin3D 는 여러분의 플레이 공간의 중심점입니다. 이 설명은 지나치게 단순하긴 한데 자세한 사항은 뒤쪽에서 살펴볼 것입니다. 물리적인 공간에서 XR 플랫폼에 의해서 트래킹되는 모든 물체는 이 중심점에 상대적으로 위치하게 됩니다.
XRCamera3D 는 XR 장치의 출력을 렌더링하는 (스테레오) 카메라를 의미합니다. 이 노드의 위치는 XR 시스템에 의해 제어되는데 XR 플랫폼이 제공하는 트래킹 정보에 의해 자동으로 업데이트됩니다.
XRController3D 는 플레이어가 사용하는 컨트롤러를 의미하며 일반적으로 양 손에 하나씩 두 개가 있습니다. 이 노드는 그 컨트롤러들의 다양한 상태 정보에 접근 가능하게 하며 플레이어가 버튼을 누르면 시그널을 발생시킵니다. 이 노드의 위치는 XR 시스템에 의해 제어되며 XR 플랫폼이 제공하는 트래킹 정보에 의해 자동으로 업데이트됩니다.
다른 XR 관련 노드들도 존재하며, 위 세 노드에 대해서도 설명할 것들이 많지만 이는 나중에 다루도록 하겠습니다.
사용할 렌더러
Godot에는 프로젝트에 대한 3가지 렌더러 옵션이 있습니다: Compatibility, Mobile, Forward+. 현재 권장 사항은 데스크톱 VR 프로젝트에 모바일 렌더러를 사용하고 Meta Quest 3과 같은 독립형 헤드셋에서 실행되는 모든 프로젝트에 호환성 렌더러를 사용하는 것입니다. XR 프로젝트는 Forward+ 렌더러로 실행되지만 다른 두 프로젝트에 비해 현재 XR에 최적화되어 있지 않습니다.
OpenXR
OpenXR은 XR 응용 프로그램에서 표준화된 API를 사용함으로써 서로 다른 XR 플랫폼에서 동작 가능하게 하는 새로운 산업 표준입니다. 이 표준은 Khronos 그룹에서 관리하는 공개 표준이므로 Godot와 아주 잘 어울립니다.
OpenXR의 Vulkan 구현은 Vulkan 시스템의 일부를 대신하여 Vulkan과 긴밀하게 통합됩니다. 이를 위해서는 Vulkan 렌더러의 특정 핵심(core) 그래픽스 기능과의 통합이 필요하며, XR 시스템을 설정하기 전에 이러한 작업이 수행되어야 합니다. 이를 통해 OpenXR이 핵심 인터페이스에 포함할지 여부가 결정됩니다.
따라서 OpenXR은 Godot 실행 시에 활성화되어야 합니다. 프로젝트 설정에서 관련된 설정을 찾으실 수 있습니다:
OpenXR과 관련된 여러 가지 다른 설정도 여기에서 찾을 수 있습니다. 이 값은 애플리케이션이 실행 중에는 바꿀 수 없습니다. 기본 설정으로 시작하겠지만, 여기에 있는 것의 자세한 정보는 설정를 참조하세요.
또한 프로젝트 설정에서 XR > 셰이더**로 이동하여 :ref:`Enabled<class_ProjectSettings_property_xr/shaders/enabled>` 상자를 선택하여 활성화해야 합니다. 완료한 후 **저장 및 다시 시작 버튼을 클릭하세요.
경고
Godot 4는 아직 개발 중이므로, 많은 포스트 프로세싱 효과들은 아직 스테레오 렌더링을 지원하지 않습니다. 사용하는 경우 부작용이 나타날 수 있습니다.
XR 씬 설정
모든 XR 애플리케이션은 최소한 XROrigin3D와 XRCamera3D 노드가 필요합니다. 또한 대부분의 경우 왼손과 오른손 두 개의:ref:XRController3D <class_xrcontroller3d>가 필요할 것입니다. 카메라와 컨트롤러 노드는 origin 노드의 자식이어야 한다는 것에 유의하세요. 이것들을 새로운 씬에 추가하고 컨트롤러 노드의 이름을 ``LeftHand``와 ``RightHand``로 변경하면 아래와 같이 될 것입니다:
다음으로 컨트롤러를 구성해야 하며, 왼손 노드를 선택하고 아래와 같이 설정합니다:
오른 손은 아래와 같습니다:
지금 이 노드들은 바닥에 위치해 있지만, 런타임에는 제대로 위치하게 될겁니다. 개발의 편의성을 위해 카메라를 위로 옮겨서 y 값을 1.7 로 설정하고 컨트롤러 노드들을 왼손과 오른손 각각 -0.5, 1.0, -0.5, 0.5, 1.0, -0.5 로 옮깁시다.
다음으로 루트 노드에 스트립트를 추가하고, 아래 코드를 스크립트에 추가합니다:
extends Node3D
var xr_interface: XRInterface
func _ready():
xr_interface = XRServer.find_interface("OpenXR")
if xr_interface and xr_interface.is_initialized():
print("OpenXR initialized successfully")
# Turn off v-sync!
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
# Change our main viewport to output to the HMD
get_viewport().use_xr = true
else:
print("OpenXR not initialized, please check if your headset is connected")
using Godot;
public partial class MyNode3D : Node3D
{
private XRInterface _xrInterface;
public override void _Ready()
{
_xrInterface = XRServer.FindInterface("OpenXR");
if(_xrInterface != null && _xrInterface.IsInitialized())
{
GD.Print("OpenXR initialized successfully");
// Turn off v-sync!
DisplayServer.WindowSetVsyncMode(DisplayServer.VSyncMode.Disabled);
// Change our main viewport to output to the HMD
GetViewport().UseXR = true;
}
else
{
GD.Print("OpenXR not initialized, please check if your headset is connected");
}
}
}
이 코드 프래그먼트는 OpenXR을 사용한다고 가정합니다. 다른 인터페이스를 사용하려는 경우 find_interface 호출을 변경할 수 있습니다.
경고
위 코드 조각에서 볼 수 있는 것처럼 v-sync는 비활성화 하였습니다. OpenXR을 사용하는 경우 렌더링 결과가 HMD로 90Hz 이상으로 전달되어야만 합니다. 여러분의 모니터가 60Hz인데 v-sync가 켜져 있으면 출력이 초당 60프레임으로 제한됩니다.
OpenXR과 같은 XR 인터페이스는 자체적인 동기화를 수행합니다.
또 유의해야 할 것은 물리 엔진은 기본적으로 60Hz로 동작하기 때문에 불안정한 결과가 나타날 수 있습니다. Engine.physics_ticks_per_second도 더 높은 값으로 설정해야 합니다.
이제 프로젝트를 실행하면 모든 것들이 잘 동작하지만 검은 화면이 보일 것입니다. 따라서 마지막으로 DirectionalLight3D와 WorldEnvironment 노드를 씬에 추가하는 것으로 마치도록 하겠습니다. 메시 인스턴스를 컨트롤러 노드의 자식으로 추가하여 임시로 손의 위치를 보여줄 수도 있습니다. 하늘을 세계 환경에 구성했는지 확인하세요.
이제 프로젝트를 실행하면 여러분은 어딘가에 떠 있는 상태로 주변을 둘러 볼 수 있게 됩니다.
참고
XR 애플리케이션에서도 기존처럼 레벨 전환을 수행할 수 있습니다. 이는 각 레벨마다 씬을 설정하는 방식인데 한 번 설정하면 레벨을 하위씬으로 불러오기 간단합니다. 만일 씬을 전환하면서 XR 설정을 복사하게 되는 경우 initialize를 여러 번 수행하지 않도록 주의하세요. XR 인터페이스에 따라 예측이 불가능한 결과가 나타날 수 있습니다.
이 기초 튜토리얼 시리즈의 나머지에서는 하나의 씬을 사용하는 게임을 만들어 보겠습니다.