-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Added an OpenXR render models demo #1218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
skyace65
merged 1 commit into
godotengine:master
from
BastiaanOlij:openxr_render_models_demo
Jul 14, 2025
+656
−0
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Normalize EOL for all files that Git considers text files. | ||
* text=auto eol=lf |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Godot 4+ specific ignores | ||
.godot/ | ||
.editorconfig | ||
/android/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# OpenXR Render models demo | ||
|
||
This is a demo showing OpenXR's render models implementation. | ||
|
||
Language: GDScript | ||
|
||
Renderer: Compatibility | ||
|
||
> [!NOTE] | ||
> | ||
> This demo requires Godot 4.5 or later | ||
|
||
## Screenshots | ||
|
||
 | ||
|
||
## How does it work? | ||
|
||
OpenXR allows us to run our application without having knowledge of the hardware being used, | ||
or that we as developers have access too at the time of developing our application. | ||
|
||
As a result we don't have direct information telling us what hardware is being used, | ||
however there are situations where we want to visually show this hardware. | ||
|
||
This specifically applies to the controllers used by the user, as showing the correct hardware | ||
improves the user's sense of immersion. | ||
|
||
The render model API allows us to enumerate the devices currently in use and then query | ||
information such as its 3D asset, its position and orientation in space, and the position | ||
and orientation of individual components of the asset. | ||
|
||
Godot's implementation hides most of the complexity of this through the OpenXRRenderModelManager | ||
node as a child of the XROrigin3D node. You can add just this node by itself and let it show | ||
all render models that are currently active, or like we do in this demo, you can add nodes | ||
in the tree of each controller to show render models related to that controller. | ||
|
||
## Action map | ||
|
||
This demo project has a barebones action map as we're only dealing with positioning. | ||
|
||
## Running on PCVR | ||
|
||
This project can be run as normal for PCVR. Ensure that an OpenXR runtime has been installed. | ||
|
||
## Running on standalone VR | ||
|
||
You must install the Android build templates and OpenXR loader plugin and configure an export template for your device. | ||
Please follow [the instructions for deploying on Android in the manual](https://docs.godotengine.org/en/stable/tutorials/xr/deploying_to_android.html). | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="CompressedTexture2D" | ||
uid="uid://btobyv4xjhltq" | ||
path.s3tc="res://.godot/imported/pattern.png-cf6f03dfd1cdd4bc35da3414e912103d.s3tc.ctex" | ||
metadata={ | ||
"imported_formats": ["s3tc_bptc"], | ||
"vram_texture": true | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://assets/pattern.png" | ||
dest_files=["res://.godot/imported/pattern.png-cf6f03dfd1cdd4bc35da3414e912103d.s3tc.ctex"] | ||
|
||
[params] | ||
|
||
compress/mode=2 | ||
compress/high_quality=false | ||
compress/lossy_quality=0.7 | ||
compress/uastc_level=0 | ||
compress/rdo_quality_loss=0.0 | ||
compress/hdr_compression=1 | ||
compress/normal_map=0 | ||
compress/channel_pack=0 | ||
mipmaps/generate=true | ||
mipmaps/limit=-1 | ||
roughness/mode=0 | ||
roughness/src_normal="" | ||
process/channel_remap/red=0 | ||
process/channel_remap/green=1 | ||
process/channel_remap/blue=2 | ||
process/channel_remap/alpha=3 | ||
process/fix_alpha_border=true | ||
process/premult_alpha=false | ||
process/normal_map_invert_y=false | ||
process/hdr_as_srgb=false | ||
process/hdr_clamp_exposure=false | ||
process/size_limit=0 | ||
detect_3d/compress_to=0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[gd_scene load_steps=5 format=3 uid="uid://cfgfwisj8m2mg"] | ||
|
||
[ext_resource type="Texture2D" uid="uid://btobyv4xjhltq" path="res://assets/pattern.png" id="1_g2tbl"] | ||
|
||
[sub_resource type="BoxShape3D" id="BoxShape3D_oq5cr"] | ||
|
||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_bqn3j"] | ||
albedo_color = Color(0.16217351, 0.546357, 0.5366536, 1) | ||
albedo_texture = ExtResource("1_g2tbl") | ||
uv1_scale = Vector3(3, 3, 3) | ||
|
||
[sub_resource type="BoxMesh" id="BoxMesh_3n43a"] | ||
material = SubResource("StandardMaterial3D_bqn3j") | ||
|
||
[node name="Box" type="RigidBody3D"] | ||
|
||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."] | ||
shape = SubResource("BoxShape3D_oq5cr") | ||
|
||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."] | ||
mesh = SubResource("BoxMesh_3n43a") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
class_name CollisionHands3D | ||
extends AnimatableBody3D | ||
|
||
func _ready(): | ||
# Make sure these are set correctly. | ||
top_level = true | ||
sync_to_physics = false | ||
process_physics_priority = -90 | ||
|
||
|
||
func _physics_process(_delta): | ||
# Follow our parent node around. | ||
var dest_transform = get_parent().global_transform | ||
|
||
# We just apply rotation for this example. | ||
global_basis = dest_transform.basis | ||
|
||
# Attempt to move to where our tracked hand is. | ||
move_and_collide(dest_transform.origin - global_position) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
uid://c5bnmb8grcumh |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
[remap] | ||
|
||
importer="texture" | ||
type="CompressedTexture2D" | ||
uid="uid://bi6bu4ng584fq" | ||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" | ||
metadata={ | ||
"vram_texture": false | ||
} | ||
|
||
[deps] | ||
|
||
source_file="res://icon.svg" | ||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] | ||
|
||
[params] | ||
|
||
compress/mode=0 | ||
compress/high_quality=false | ||
compress/lossy_quality=0.7 | ||
compress/uastc_level=0 | ||
compress/rdo_quality_loss=0.0 | ||
compress/hdr_compression=1 | ||
compress/normal_map=0 | ||
compress/channel_pack=0 | ||
mipmaps/generate=false | ||
mipmaps/limit=-1 | ||
roughness/mode=0 | ||
roughness/src_normal="" | ||
process/channel_remap/red=0 | ||
process/channel_remap/green=1 | ||
process/channel_remap/blue=2 | ||
process/channel_remap/alpha=3 | ||
process/fix_alpha_border=true | ||
process/premult_alpha=false | ||
process/normal_map_invert_y=false | ||
process/hdr_as_srgb=false | ||
process/hdr_clamp_exposure=false | ||
process/size_limit=0 | ||
detect_3d/compress_to=1 | ||
svg/scale=1.0 | ||
editor/scale_with_editor_scale=false | ||
editor/convert_colors_with_editor_theme=false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
[gd_scene load_steps=13 format=3 uid="uid://btli1dajen53o"] | ||
|
||
[ext_resource type="Script" uid="uid://bqa4r4n7b6d7s" path="res://start_vr.gd" id="1_1bvp3"] | ||
[ext_resource type="Script" uid="uid://c5bnmb8grcumh" path="res://collision_hands.gd" id="1_ig7tw"] | ||
[ext_resource type="Texture2D" uid="uid://btobyv4xjhltq" path="res://assets/pattern.png" id="2_h2yge"] | ||
[ext_resource type="PackedScene" uid="uid://cfgfwisj8m2mg" path="res://box.tscn" id="3_1bvp3"] | ||
[ext_resource type="PackedScene" uid="uid://c7ohc2o1shtu7" path="res://wall.tscn" id="5_lquwl"] | ||
|
||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_7dm0k"] | ||
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) | ||
ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) | ||
|
||
[sub_resource type="Sky" id="Sky_ig7tw"] | ||
sky_material = SubResource("ProceduralSkyMaterial_7dm0k") | ||
|
||
[sub_resource type="Environment" id="Environment_0xm2m"] | ||
background_mode = 2 | ||
sky = SubResource("Sky_ig7tw") | ||
tonemap_mode = 2 | ||
|
||
[sub_resource type="SphereShape3D" id="SphereShape3D_0xm2m"] | ||
radius = 0.02 | ||
|
||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_lquwl"] | ||
|
||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7mycd"] | ||
albedo_color = Color(0.3241276, 0.50004333, 0.2159737, 1) | ||
albedo_texture = ExtResource("2_h2yge") | ||
uv1_scale = Vector3(100, 100, 100) | ||
|
||
[sub_resource type="PlaneMesh" id="PlaneMesh_272bh"] | ||
material = SubResource("StandardMaterial3D_7mycd") | ||
size = Vector2(1000, 1000) | ||
|
||
[node name="Main" type="Node3D"] | ||
|
||
[node name="StartVR" type="Node3D" parent="."] | ||
script = ExtResource("1_1bvp3") | ||
|
||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] | ||
transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0) | ||
shadow_enabled = true | ||
shadow_bias = 0.01 | ||
directional_shadow_max_distance = 50.0 | ||
|
||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] | ||
environment = SubResource("Environment_0xm2m") | ||
|
||
[node name="XROrigin3D" type="XROrigin3D" parent="."] | ||
|
||
[node name="XRCamera3D" type="XRCamera3D" parent="XROrigin3D"] | ||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.7, 0) | ||
|
||
[node name="OpenXRRenderManager" type="OpenXRRenderModelManager" parent="XROrigin3D"] | ||
tracker = 1 | ||
|
||
[node name="LeftHand" type="XRController3D" parent="XROrigin3D"] | ||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 1, -0.5) | ||
tracker = &"left_hand" | ||
pose = &"grip" | ||
|
||
[node name="CollisionHands3D" type="AnimatableBody3D" parent="XROrigin3D/LeftHand"] | ||
script = ExtResource("1_ig7tw") | ||
metadata/_custom_type_script = "uid://c5bnmb8grcumh" | ||
|
||
[node name="OpenXRRenderManager" type="OpenXRRenderModelManager" parent="XROrigin3D/LeftHand/CollisionHands3D"] | ||
tracker = 2 | ||
make_local_to_pose = "grip" | ||
|
||
[node name="CollisionShape3D" type="CollisionShape3D" parent="XROrigin3D/LeftHand/CollisionHands3D"] | ||
shape = SubResource("SphereShape3D_0xm2m") | ||
|
||
[node name="RightHand" type="XRController3D" parent="XROrigin3D"] | ||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 1, -0.5) | ||
tracker = &"right_hand" | ||
pose = &"grip" | ||
|
||
[node name="CollisionHands3D" type="AnimatableBody3D" parent="XROrigin3D/RightHand"] | ||
script = ExtResource("1_ig7tw") | ||
metadata/_custom_type_script = "uid://c5bnmb8grcumh" | ||
|
||
[node name="OpenXRRenderManager" type="OpenXRRenderModelManager" parent="XROrigin3D/RightHand/CollisionHands3D"] | ||
tracker = 3 | ||
make_local_to_pose = "grip" | ||
|
||
[node name="CollisionShape3D" type="CollisionShape3D" parent="XROrigin3D/RightHand/CollisionHands3D"] | ||
shape = SubResource("SphereShape3D_0xm2m") | ||
|
||
[node name="Floor" type="StaticBody3D" parent="."] | ||
|
||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"] | ||
shape = SubResource("WorldBoundaryShape3D_lquwl") | ||
|
||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Floor"] | ||
mesh = SubResource("PlaneMesh_272bh") | ||
|
||
[node name="Box" parent="." instance=ExtResource("3_1bvp3")] | ||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.75, 0.5, -0.75) | ||
|
||
[node name="Wall01" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(0.5077975, 0.073525466, 0.8583331, -0.14741239, 0.989072, 0.0024858303, -0.8487705, -0.12779121, 0.5130869, -1.3576927, -0.4236443, 0) | ||
|
||
[node name="Wall02" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(-0.4400646, -0.09660582, 0.89275444, 0, 0.9941961, 0.10758293, -0.89796615, 0.047343437, -0.43751052, 2.5047212, -0.106753826, 0.0325222) | ||
|
||
[node name="Wall03" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(0.584169, -0.048437964, 0.8101854, -0.1719119, 0.9681845, 0.181838, -0.7932168, -0.24550463, 0.5572562, 2.4887834, -0.7894809, 2.6100364) | ||
|
||
[node name="Wall04" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(-0.63450754, -0.2243154, 0.7396504, -0.12261418, 0.9740546, 0.19021934, -0.763129, 0.030003972, -0.64554924, -1.2827711, -0.22003722, 2.6100364) | ||
|
||
[node name="Wall05" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(-0.9373456, 0.2908417, 0.1918185, 0.3214552, 0.93427694, 0.1542501, -0.13434927, 0.20624672, -0.9692331, 0.36298275, -0.48010635, -3.1081657) | ||
|
||
[node name="Wall06" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(-0.990934, 0, 0.13434926, 0, 1, 0, -0.13434926, 0, -0.990934, 0.75976896, -0.70440745, 4.5405197) | ||
|
||
[node name="Wall07" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(0.02368374, 0.13314083, -0.99081427, -0.16938388, 0.97729725, 0.12727568, 0.9852657, 0.16481358, 0.045697965, 3.8073082, -0.5026467, 0.84226894) | ||
|
||
[node name="Wall08" parent="." instance=ExtResource("5_lquwl")] | ||
transform = Transform3D(0.023540916, 0.2297096, -0.9729746, -0.2009241, 0.95447266, 0.22048022, 0.97932404, 0.19030367, 0.06862336, -3.4319887, -0.45930338, 0.84226894) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.