godotengine/godot
OpenXR
Purpose
modules/openxr/ is Godot's primary XR runtime integration. It implements an XRInterface against the Khronos OpenXR standard, which on the user's machine connects to whatever OpenXR runtime is installed (Meta Quest, SteamVR, Monado, Varjo, Pico, …). The module also ships an editor for OpenXR action maps so projects can bind controller inputs to abstract actions.
Directory layout
modules/openxr/
├── openxr_api.{cpp,h} Wrapper around OpenXR C API; the heavy-lifting class
├── openxr_interface.{cpp,h} XRInterface implementation that talks to openxr_api
├── action_map/ OpenXRActionMap, OpenXRAction, OpenXRBindingProfile,
│ OpenXRInteractionProfile resources
├── extensions/ Per-extension support (passthrough, foveation, hand tracking,
│ face tracking, body tracking, eye tracking, fb_*, varjo_*)
├── editor/ Action map editor + interaction profile editor (editor plugin)
├── scene/ OpenXRHand, OpenXRCompositionLayer, OpenXRVisibilityMask,
│ OpenXRRenderModel scene-tree nodes
├── doc_classes/ XML class reference
├── util.{cpp,h} OpenXR error logging + utility wrappers
└── register_types.cppthirdparty/openxr/ ships the OpenXR SDK headers + loader.
What OpenXR brings
The core OpenXR API exposed through this module:
- Sessions — start/stop XR; manage focus events.
- Spaces — local, stage, view spaces; reference frames for poses.
- Composition layers — projection layers (the rendered scene), quad layers (UI overlays), cylinder, equirect, cube, passthrough layers.
- Input — action sets with abstract actions (
pose,bool,float,vec2,vibration) bound to interaction profiles per controller type. - Rendering — swapchains for left/right eye, multiview rendering, foveated rendering hints.
OpenXRInterface
OpenXRInterface (openxr_interface.cpp) is the XRInterface subclass. It:
- Drives the OpenXR session lifecycle (
xrBeginSession,xrEndSession). - Calls
xrWaitFrame,xrBeginFrame,xrEndFramearound each engine frame. - Acquires per-eye swapchain images, hands them to the rendering server as render targets.
- Polls trackers and reports them through
XRServer::add_tracker/XRTracker::set_pose. - Handles per-frame VRS (variable-rate shading) attachments when the runtime supports
XR_FB_foveation_vulkan/XR_VARJO_foveated_rendering.
Action map
The action map (under action_map/) is the declarative input system OpenXR encourages:
OpenXRAction— an abstract action likeselect,grip_force,aim_pose,haptic_left.OpenXRActionSet— a group of actions that can be activated together (e.g., menu vs gameplay).OpenXRInteractionProfile— per-device binding (/interaction_profiles/oculus/touch_controller→ which actions map to which physical inputs).OpenXRBindingModifier— modifiers like dpad emulation, threshold, value transformations.
Actions surface to the scripting side as XRControllerTracker axes/buttons. The editor plugin under editor/ lets users edit action maps in a visual interface; the result is saved as default_action_map.tres (or per-project) and loaded at startup.
Per-frame flow
sequenceDiagram
participant Engine as Godot main thread
participant XR as OpenXRInterface
participant API as OpenXR runtime
Engine->>XR: process()
XR->>API: xrWaitFrame, xrBeginFrame
API-->>XR: frame timing + predicted pose
XR->>API: xrSyncActions
XR->>API: xrLocateSpace per tracker
XR-->>Engine: tracker poses via XRServer
Engine->>Engine: scripts run; nodes consume controller poses
Engine->>XR: pre_draw_viewport
XR->>API: xrAcquireSwapchainImage (left + right eye)
XR-->>Engine: per-eye render targets
Engine->>RenderingServer: render scene to per-eye targets
Engine->>XR: post_draw_viewport
XR->>API: xrReleaseSwapchainImage, xrEndFrameExtensions
extensions/ registers OpenXRExtensionWrapper subclasses for vendor + Khronos extensions. Each wrapper:
- Declares the OpenXR extension name(s) it requires.
- Hooks in at session startup if the runtime advertises the extension.
- Provides per-frame logic when needed.
Wrappers shipped in-tree include:
| Wrapper | Extension(s) | Adds |
|---|---|---|
OpenXRHTCViveTrackerExtension |
XR_HTCX_vive_tracker_interaction |
Vive tracker support |
OpenXRHandTrackingExtension |
XR_EXT_hand_tracking |
Articulated hand poses |
OpenXRFbHandTrackingMeshExtension |
XR_FB_hand_tracking_mesh |
Hand mesh data |
OpenXRFbBodyTrackingExtension |
XR_FB_body_tracking |
Whole-body tracking |
OpenXREyeGazeInteractionExtension |
XR_EXT_eye_gaze_interaction |
Eye gaze pose |
OpenXRFaceTrackingExtension |
XR_FB_face_tracking2 |
Face blend shapes |
OpenXRPalmPoseExtension |
XR_EXT_palm_pose |
Palm-relative pose |
OpenXRCompositionLayerExtension |
XR_KHR_composition_layer_* |
Quad/cylinder/equirect layers |
OpenXRFbPassthroughExtension |
XR_FB_passthrough |
Color passthrough |
OpenXRMetaPerformanceMetricsExtension |
XR_META_performance_metrics |
Performance counters |
OpenXRFbFoveationExtension |
XR_FB_foveation* |
Fixed/eye-tracked foveated rendering |
The list is long and continues to grow with each OpenXR release.
Scene-tree nodes
scene/ adds Godot nodes that wrap OpenXR-specific functionality:
OpenXRHand— pulls hand tracker data and applies it to a skeleton.OpenXRCompositionLayer(andOpenXRCompositionLayerQuad,OpenXRCompositionLayerCylinder,OpenXRCompositionLayerEquirect) — render-to-texture surfaces submitted as native composition layers (lower latency + crisper text than rendering inside the projection layer).OpenXRVisibilityMask— render the runtime's visibility mask to skip unseen pixels.OpenXRRenderModel— render the runtime-supplied controller mesh.
Key abstractions
| Abstraction | File | Role |
|---|---|---|
OpenXRAPI |
modules/openxr/openxr_api.cpp |
Wraps the OpenXR C API |
OpenXRInterface |
modules/openxr/openxr_interface.cpp |
XRInterface impl |
OpenXRActionMap, OpenXRAction, OpenXRInteractionProfile, OpenXRBindingModifier |
modules/openxr/action_map/ |
Resources for action map authoring |
OpenXRExtensionWrapper |
modules/openxr/extensions/openxr_extension_wrapper.h |
Per-extension plugin |
OpenXRHand, OpenXRCompositionLayer*, OpenXRVisibilityMask |
modules/openxr/scene/ |
Scene-tree integration |
Integration points
- Registered with
XRServerfromregister_types.cpp. Becomes the active interface when the project settingxr/openxr/enabled = true. - Renders through
RenderingServerlike any other viewport; the per-eye render targets are built viaviewport_set_use_xrsemantics. - Action map resources are persisted under the project; the action map editor is available under the "OpenXR" menu in the editor.
Entry points for modification
- New OpenXR extension → add a wrapper in
extensions/, register it inregister_types.cpp. Follow the pattern of existing wrappers. - Custom interaction profile → either define a new
OpenXRInteractionProfileresource, or write anOpenXRBindingModifierfor the specific controller. - Updating OpenXR loader → bump
thirdparty/openxr/and patch any deprecated function calls inopenxr_api.cpp.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.