diff --git a/xr/mobile_vr_interface_demo/.editorconfig b/xr/mobile_vr_interface_demo/.editorconfig new file mode 100644 index 00000000..f28239ba --- /dev/null +++ b/xr/mobile_vr_interface_demo/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/xr/mobile_vr_interface_demo/README.md b/xr/mobile_vr_interface_demo/README.md new file mode 100644 index 00000000..4daf41f3 --- /dev/null +++ b/xr/mobile_vr_interface_demo/README.md @@ -0,0 +1,26 @@ +# Mobile VR interfae demo + +This is a really simple demo that shows how the mobile VR interface can be enabled. +This is a great little project to test stereo rendering on desktop without needing XR hardware. +When used on mobile devices simple 3DOF headtracking can be tested. + +Language: GDScript + +Renderer: Compatibility, Mobile, Forward+ + +Check out this demo on the asset library: https://godotengine.org/asset-library/asset/0000 + +## How does it work? + +This sample shows the simplest form for enabling and testing an XR application. +It uses the build in Mobile VR Interface. + +There is simple left/right/up/down movement on desktop. + +## Shortcomings + +Note that currently lens distortion in the mobile VR interface is **not** supported in the compatibility renderer. + +## Screenshots + +![Screenshot](screenshots/mobile_vr_interface_demo.png) diff --git a/xr/mobile_vr_interface_demo/icon.svg b/xr/mobile_vr_interface_demo/icon.svg new file mode 100644 index 00000000..b370ceb7 --- /dev/null +++ b/xr/mobile_vr_interface_demo/icon.svg @@ -0,0 +1 @@ + diff --git a/xr/mobile_vr_interface_demo/icon.svg.import b/xr/mobile_vr_interface_demo/icon.svg.import new file mode 100644 index 00000000..edcb2139 --- /dev/null +++ b/xr/mobile_vr_interface_demo/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://w0uxqbioh10s" +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 diff --git a/xr/mobile_vr_interface_demo/main.gd b/xr/mobile_vr_interface_demo/main.gd new file mode 100644 index 00000000..efda161b --- /dev/null +++ b/xr/mobile_vr_interface_demo/main.gd @@ -0,0 +1,34 @@ +extends Node3D + +var xr_interface : MobileVRInterface + +# Called when the node enters the scene tree for the first time. +func _ready(): + xr_interface = XRServer.find_interface("Native mobile") + if xr_interface and xr_interface.initialize(): + # Disable lens distortion. + # xr_interface.k1 = 0.0 + # xr_interface.k2 = 0.0 + + # setup viewport + var vp = get_viewport() + vp.use_xr = true + vp.vrs_mode = Viewport.VRS_XR + else: + # How did we get here? + get_tree().quit() + +func _process(delta): + var dir : Vector2 = Vector2() + + if Input.is_action_pressed("ui_left"): + dir.x = -1.0 + elif Input.is_action_pressed("ui_right"): + dir.x = 1.0 + if Input.is_action_pressed("ui_up"): + dir.y = -1.0 + elif Input.is_action_pressed("ui_down"): + dir.y = 1.0 + + $XROrigin3D.global_position += $XROrigin3D.global_transform.basis.x * dir.x * delta + $XROrigin3D.global_position += $XROrigin3D.global_transform.basis.z * dir.y * delta diff --git a/xr/mobile_vr_interface_demo/main.gd.uid b/xr/mobile_vr_interface_demo/main.gd.uid new file mode 100644 index 00000000..37c134d4 --- /dev/null +++ b/xr/mobile_vr_interface_demo/main.gd.uid @@ -0,0 +1 @@ +uid://c1jgdguonfwbw diff --git a/xr/mobile_vr_interface_demo/main.tscn b/xr/mobile_vr_interface_demo/main.tscn new file mode 100644 index 00000000..23bbc0e4 --- /dev/null +++ b/xr/mobile_vr_interface_demo/main.tscn @@ -0,0 +1,73 @@ +[gd_scene load_steps=11 format=3 uid="uid://bvdovvya3m7sx"] + +[ext_resource type="Script" uid="uid://c1jgdguonfwbw" path="res://main.gd" id="1_1u602"] +[ext_resource type="Texture2D" uid="uid://br4k6sn2rvgj" path="res://pattern.png" id="2_imhd6"] +[ext_resource type="PackedScene" uid="uid://8m50ra15rpq1" path="res://wall.tscn" id="4_fdaxx"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_beswd"] +sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) +ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1) + +[sub_resource type="Sky" id="Sky_uvncs"] +sky_material = SubResource("ProceduralSkyMaterial_beswd") + +[sub_resource type="Environment" id="Environment_rgp66"] +background_mode = 2 +sky = SubResource("Sky_uvncs") +glow_enabled = true +glow_intensity = 1.22 +volumetric_fog_density = 0.001 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0wgu4"] +albedo_color = Color(3.3691526e-07, 0.7481091, 0.1272395, 1) +albedo_texture = ExtResource("2_imhd6") +uv1_scale = Vector3(5, 5, 5) + +[sub_resource type="PlaneMesh" id="PlaneMesh_y2phs"] +material = SubResource("StandardMaterial3D_0wgu4") +size = Vector2(25, 25) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_a1cqg"] +albedo_color = Color(0.713726, 0.545098, 0.780392, 1) +albedo_texture = ExtResource("2_imhd6") +uv1_scale = Vector3(8, 2, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_1vrbc"] +material = SubResource("StandardMaterial3D_a1cqg") +size = Vector3(4, 3, 1) + +[node name="Main" type="Node3D"] +script = ExtResource("1_1u602") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.86602384, -0.43301564, 0.2500005, 0, 0.49999815, 0.8660265, -0.50000286, 0.7499995, -0.4330103, 0, 0, 0) +shadow_enabled = true + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_rgp66") + +[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.5, 0) + +[node name="Floor" type="MeshInstance3D" parent="."] +mesh = SubResource("PlaneMesh_y2phs") + +[node name="Wall01" type="MeshInstance3D" parent="."] +transform = Transform3D(0.968213, -0.250127, 0, 0.250127, 0.968213, 0, 0, 0, 1, 0, 0.82946, -6.87257) +mesh = SubResource("BoxMesh_1vrbc") + +[node name="Wall02" type="MeshInstance3D" parent="."] +transform = Transform3D(0.674941, 0.180131, 0.715546, -0.257858, 0.966183, 0, -0.691348, -0.184509, 0.698565, -3.04544, 0.82946, -5.53616) +mesh = SubResource("BoxMesh_1vrbc") + +[node name="Wall03" parent="." instance=ExtResource("4_fdaxx")] +transform = Transform3D(0.90396, 0.0774667, -0.154893, 0.403151, -0.275157, 0.248304, -0.142568, -0.286902, -0.279961, -3.26749, 3.93987, -7.24752) + +[node name="Wall04" type="MeshInstance3D" parent="."] +transform = Transform3D(0.491527, 0, -0.870862, 0, 2.43615, 0, 0.870862, 0, 0.491527, 2.68331, 2.52217, -4.7792) +mesh = SubResource("BoxMesh_1vrbc") + +[node name="Wall05" parent="." instance=ExtResource("4_fdaxx")] +transform = Transform3D(0.941075, 0.0774667, 0.112959, -0.0781437, -0.275157, 0.295486, 0.329045, -0.286902, -0.25289, 2.33372, 3.46393, -10.7686) diff --git a/xr/mobile_vr_interface_demo/pattern.png b/xr/mobile_vr_interface_demo/pattern.png new file mode 100644 index 00000000..8bf420b0 Binary files /dev/null and b/xr/mobile_vr_interface_demo/pattern.png differ diff --git a/xr/mobile_vr_interface_demo/pattern.png.import b/xr/mobile_vr_interface_demo/pattern.png.import new file mode 100644 index 00000000..304a5240 --- /dev/null +++ b/xr/mobile_vr_interface_demo/pattern.png.import @@ -0,0 +1,41 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://br4k6sn2rvgj" +path.s3tc="res://.godot/imported/pattern.png-888ea151ee9fa7a079d3252596260765.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://pattern.png" +dest_files=["res://.godot/imported/pattern.png-888ea151ee9fa7a079d3252596260765.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 diff --git a/xr/mobile_vr_interface_demo/project.godot b/xr/mobile_vr_interface_demo/project.godot new file mode 100644 index 00000000..817e49f5 --- /dev/null +++ b/xr/mobile_vr_interface_demo/project.godot @@ -0,0 +1,28 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Test Stereo" +run/main_scene="res://main.tscn" +config/features=PackedStringArray("4.5", "Forward Plus") +config/icon="res://icon.svg" +run/main_scene.mobile="res://main_mobile.tscn" + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" + +[xr] + +openxr/foveation_level=3 +openxr/foveation_dynamic=true +shaders/enabled=true diff --git a/xr/mobile_vr_interface_demo/screenshots/mobile_vr_interface_demo.png b/xr/mobile_vr_interface_demo/screenshots/mobile_vr_interface_demo.png new file mode 100644 index 00000000..38fbb10e Binary files /dev/null and b/xr/mobile_vr_interface_demo/screenshots/mobile_vr_interface_demo.png differ diff --git a/xr/mobile_vr_interface_demo/screenshots/mobile_vr_interface_demo.png.import b/xr/mobile_vr_interface_demo/screenshots/mobile_vr_interface_demo.png.import new file mode 100644 index 00000000..6bf43b7c --- /dev/null +++ b/xr/mobile_vr_interface_demo/screenshots/mobile_vr_interface_demo.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://0fka4gxxuir1" +path="res://.godot/imported/mobile_vr_interface_demo.png-cf181071eac4076f0e745f8ad4b3c194.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://screenshots/mobile_vr_interface_demo.png" +dest_files=["res://.godot/imported/mobile_vr_interface_demo.png-cf181071eac4076f0e745f8ad4b3c194.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 diff --git a/xr/mobile_vr_interface_demo/wall.tscn b/xr/mobile_vr_interface_demo/wall.tscn new file mode 100644 index 00000000..75cdf102 --- /dev/null +++ b/xr/mobile_vr_interface_demo/wall.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=4 format=3 uid="uid://8m50ra15rpq1"] + +[ext_resource type="Texture2D" uid="uid://br4k6sn2rvgj" path="res://pattern.png" id="1_eektq"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_a1cqg"] +albedo_color = Color(0.713726, 0.545098, 0.780392, 1) +albedo_texture = ExtResource("1_eektq") +uv1_scale = Vector3(8, 2, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_1vrbc"] +material = SubResource("StandardMaterial3D_a1cqg") +size = Vector3(4, 3, 1) + +[node name="Wall" type="Node3D"] +transform = Transform3D(1, 0, 0, 0, 0.405, 0, 0, 0, 0.405, 0, 0, 0) + +[node name="Wall03" type="MeshInstance3D" parent="."] +transform = Transform3D(2.472, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.83988, 0) +mesh = SubResource("BoxMesh_1vrbc") +skeleton = NodePath("../..")