OpenXR Settings
OpenXR has its own set of settings that are applied when OpenXR starts. While it is possible for OpenXR extensions implemented through Godot plugins to add additional settings, we will only discuss the settings in the core of Godot here.
Enabled
This setting enables the OpenXR module when Godot starts. This is required when the Vulkan backend is used. For other backends you can enable OpenXR at any time by calling initialize
on the OpenXRInterface.
This also needs to be enabled to get access to the action map editor.
You can use the --xr-mode on
command line switch to force this to on.
Default Action Map
This specifies the path of the action map file that OpenXR will load and communicate to the XR Runtime.
Form Factor
This specifies whether your game is designed for:
Head Mounted
devices such as a Meta Quest, Valve Index, or Magic Leap,Handheld
devices such as phones.
If the device on which you run your game does not match the selection here, OpenXR will fail to initialise.
View Configuration
This specifies the view configuration your game is designed for:
Mono
, your game provides a single image output. E.g. phone based AR;Stereo
, your game provides stereo image output. E.g. head mounted devices.
If the device on which you run your game does not match the selection here, OpenXR will fail to initialise.
INFO
OpenXR has additional view configurations for very specific devices that Godot doesn't support yet. For instance, Varjo headsets have a quad view configuration that outputs two sets of stereo images. These may be supported in the near future.
Reference Space
Within XR all elements like the player's head and hands are tracked within a tracking volume. At the base of this tracking volume is our origin point, which maps our virtual space to the real space. There are however different scenarios that place this point in different locations, depending on the XR system used. In OpenXR these scenarios are well defined and selected by setting a reference space.
Local
The local reference space places our origin point at the player's head by default. Some XR runtimes will do this each time your game starts, others will make the position persist over sessions.
This reference space however does not prevent the user from walking away so you will need to detect if the user does so if you wish to prevent the user from leaving the vehicle they are controlling, which could potentially be game breaking.
This reference space is the best option for games like flight simulators or racing simulators where we want to place the XROrigin3D node where the player's head should be.
When the user enacts the recenter option on their headset, the method of which is different per XR runtime, the XR runtime will move the XRCamera3D to the XROrigin3D node. The OpenXRInterface will also emit the pose_recentered
signal so your game can react accordingly.
INFO
Any other XR tracked elements such as controllers or anchors will also be adjusted accordingly.
WARNING
You should not call center_on_hmd
when using this reference space.
Stage
The stage reference space is our default reference space and places our origin point at the center of our play space. For XR runtimes that allow you to draw out a guardian boundary this location and its orientation is often set by the user. Other XR runtimes may decide on the placement of this point by other means. It is however a stationary point in the real world.
This reference space is the best option for room scale games where the user is expected to walk around a larger space, or for games where there is a need to switch between game modes. See Room scale in XR for more information.
When the user enacts the recenter option on their headset, the method of which is different per XR runtime, the XR runtime will not change the origin point. The OpenXRInterface will emit the pose_recentered
signal and it is up to the game to react appropriately. Not doing so will prevent your game from being accepted on various stores.
In Godot you can do this by calling the center_on_hmd
function on the XRServer:
Calling
XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, true)
will move the XRCamera3D node to the XROrigin3D node similar to theLocal
reference space.Calling
XRServer.center_on_hmd(XRServer.RESET_BUT_KEEP_TILT, true)
will move the XRCamera3D node above the XROrigin3D node keeping the player's height, similar to theLocal Floor
reference space.
INFO
Any other XR tracked elements such as controllers or anchors will also be adjusted accordingly.
Local Floor
The local floor reference space is similar to the local reference space as it positions the origin point where the player is. In this mode however the height of the player is kept. Same as with the local reference space, some XR runtimes will persist this location over sessions.
It is thus not guaranteed the player will be standing on the origin point, the only guarantee is that they were standing there when the user last recentered. The player is thus also free to walk away.
This reference space is the best option of games where the user is expected to stand in the same location or for AR type games where the user's interface elements are bound to the origin node and are quickly placed at the player's location on recenter.
When the user enacts the recenter option on their headset, the method of which is different per XR runtime, the XR runtime will move the XRCamera3D above the XROrigin3D node but keeping the player's height. The OpenXRInterface will also emit the pose_recentered
signal so your game can react accordingly.
WARNING
Be careful using this mode in combination with virtual movement of the player. The user recentering in this scenario can be unpredictable unless you counter the move when handling the recenter signal. This can even be game breaking as the effect in this scenario would be the player teleporting to whatever abstract location the origin point was placed at during virtual movement, including the ability for players teleporting into locations that should be off limits. It is better to use the Stage mode in this scenario and limit resetting to orientation only when a pose_recentered
signal is received.
INFO
Any other XR tracked elements such as controllers or anchors will also be adjusted accordingly.
WARNING
You should not call center_on_hmd
when using this reference space.
Environment Blend Mode
The environment blend mode defines how our rendered output is blended into "the real world" provided this is supported by the headset.
Opaque
means our output obscures the real world, we are in VR mode.Additive
means our output is added to the real world, this is an AR mode where optics do not allow us to fully obscure the real world (e.g. Hololens),Alpha
means our output is blended with the real world using the alpha output (viewport should have transparent background enabled), this is an AR mode where optics can fully obscure the real world (Magic Leap, all pass through devices, etc.).
If a mode is selected that is not supported by the headset, the first available mode will be selected.
INFO
Some OpenXR devices have separate systems for enabling/disabling passthrough. From Godot 4.3 onwards selecting the alpha blend mode will also perform these extra steps. This does require the latest vendor plugin to be installed.
Foveation Level
Sets the foveation level used when rendering provided this feature is supported by the hardware used. Foveation is a technique where the further away from the center of the viewport we render content, the lower resolution we render at. Most XR runtimes only support fixed foveation, but some will take eye tracking into account and use the focal point for this effect.
The higher the level, the better the performance gains, but also the more reduction in quality there is in the users peripheral vision.
INFO
Compatibility renderer only, for Mobile and Forward+ renderer, set the vrs_mode
property on Viewport to VRS_XR
.
WARNING
This feature is disabled if post effects are used such as glow, bloom, or DOF.
Foveation Dynamic
When enabled the foveation level will be adjusted automatically depending on current GPU load. It will be adjusted between low and the select foveation level in the previous setting. It is therefore best to combine this setting with foveation level set to high.
INFO
Compatibility renderer only
Submit Depth Buffer
If enabled an OpenXR supplied depth buffer will be used while rendering which is submitted alongside the rendered image. The XR runtime can use this for improved reprojection.
INFO
Enabling this feature will disable stencil support during rendering. Not many XR runtimes make use of this, it is advised to leave this setting off unless it provides noticeable benefits for your use case.
Startup Alert
If enabled, this will result in an alert message presented to the user if OpenXR fails to start. We don't always receive feedback from the XR system as to why starting fails. If we do, we log this to the console. Common failure reasons are:
No OpenXR runtime is installed on the host system.
Microsoft's WMR OpenXR runtime is currently active, this only supports DirectX and will fail if OpenGL or Vulkan is used.
SteamVR is used but no headset is connected/turned on.
Disable this if you support a fallback mode in your game so it can be played in desktop mode when no VR headset is connected, or if you're handling the failure condition yourself by checking OpenXRInterface.is_initialized()
.
Extensions
This subsection provides access to various optional OpenXR extensions.
Hand Tracking
This enables the hand tracking extension when supported by the device used. This is on by default for legacy reasons. The hand tracking extension provides access to data that allows you to visualise the user's hands with correct finger positions. Depending on platform capabilities the hand tracking data can be inferred from controller inputs, come from data gloves, come from optical hand tracking sensors or any other applicable source.
If your game only supports controllers this should be turned off.
See the chapter on OpenXR hand tracking for additional details.
Eye Gaze Interaction
This enables the eye gaze interaction extension when supported by the device used. When enabled we will get feedback from eye tracking through a pose situated between the user's eyes orientated in the direction the user is looking. This will be a unified orientation.
In order to use this functionality you need to edit your action map and add a new pose action, say eye_pose
. Now add a new interaction profile for the eye gaze interaction and map the eye_pose
:
Don't forget to save!
Next add a new XRController3D node to your origin node and set its tracker
property to /user/eyes_ext
and set its pose
property to eye_pose
.
Now you can add things to this controller node such as a raycast, and control things with your eyes.