add vr template project

This commit is contained in:
Guillaume Vern
2025-10-08 11:10:13 +02:00
parent 2cda32f24c
commit 97f183e59f
613 changed files with 37826 additions and 1499 deletions
+79
View File
@@ -0,0 +1,79 @@
@tool
class_name XRToolsFade
extends Node3D
## XR Tools Fade Script
##
## This script manages fading the view.
# Dictionary of fade requests
var _faders : Dictionary = {}
# Fade update flag
var _update : bool = false
# Fade mesh
var _mesh : MeshInstance3D
# Fade shader material
var _material : ShaderMaterial
# Add support for is_xr_class on XRTools classes
func is_xr_class(name : String) -> bool:
return name == "XRToolsFade"
# Called when the fade node is ready
func _ready() -> void:
# Add to the fade_mesh group - in the future this should be replaced with
# static instances.
add_to_group("fade_mesh")
# Get the mesh and material
_mesh = $FadeMesh
_material = _mesh.get_surface_override_material(0)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta : float) -> void:
# Skip if nothing to update
if not _update:
return
# Calculate the cumulative shade color
var fade := Color(1, 1, 1, 0)
var show := false
for whom in _faders:
var color := _faders[whom] as Color
fade = fade.blend(color)
show = true
# Set the shader and show if necessary
_material.set_shader_parameter("albedo", fade)
_mesh.visible = show
_update = false
# Set the fade level
func set_fade_level(p_whom : Variant, p_color : Color) -> void:
# Test if fading is needed
if p_color.a > 0:
# Set the fade level
_faders[p_whom] = p_color
_update = true
elif _faders.erase(p_whom):
# Fade erased
_update = true
## Set the fade level on the fade instance
static func set_fade(p_whom : Variant, p_color : Color) -> void:
# In the future this use of groups should be replaced by static instances.
var tree := Engine.get_main_loop() as SceneTree
for node in tree.get_nodes_in_group("fade_mesh"):
var fade := node as XRToolsFade
if fade:
fade.set_fade_level(p_whom, p_color)
@@ -0,0 +1 @@
uid://rq4v3tvv27ap
@@ -0,0 +1,13 @@
shader_type spatial;
render_mode depth_test_disabled, skip_vertex_transform, unshaded, cull_disabled;
uniform vec4 albedo : source_color;
void vertex() {
POSITION = vec4(VERTEX.x, -VERTEX.y, 0.0, 1.0);
}
void fragment() {
ALBEDO = albedo.rgb;
ALPHA = albedo.a;
}
@@ -0,0 +1 @@
uid://dnhcvacjaicgm
+21
View File
@@ -0,0 +1,21 @@
[gd_scene load_steps=5 format=3 uid="uid://wtpox7m5vu2b"]
[ext_resource type="Script" path="res://addons/godot-xr-tools/effects/fade.gd" id="1_6667f"]
[ext_resource type="Shader" path="res://addons/godot-xr-tools/effects/fade.gdshader" id="1_tjen8"]
[sub_resource type="QuadMesh" id="QuadMesh_aqp6r"]
custom_aabb = AABB(-5000, -5000, -5000, 10000, 10000, 10000)
size = Vector2(2, 2)
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xjgy8"]
render_priority = 50
shader = ExtResource("1_tjen8")
shader_parameter/albedo = Color(0, 0, 0, 1)
[node name="Fade" type="Node3D"]
script = ExtResource("1_6667f")
[node name="FadeMesh" type="MeshInstance3D" parent="."]
visible = false
mesh = SubResource("QuadMesh_aqp6r")
surface_material_override/0 = SubResource("ShaderMaterial_xjgy8")
+195
View File
@@ -0,0 +1,195 @@
@tool
class_name XRToolsVignette
extends Node3D
@export var radius : float = 1.0: set = set_radius
@export var fade : float = 0.05: set = set_fade
@export var steps : int = 32: set = set_steps
@export var auto_adjust : bool = true: set = set_auto_adjust
@export var auto_inner_radius : float = 0.35
@export var auto_fade_out_factor : float = 1.5
@export var auto_fade_delay : float = 1.0
@export var auto_rotation_limit : float = 20.0: set = set_auto_rotation_limit
@export var auto_velocity_limit : float = 10.0
var material : ShaderMaterial = preload("res://addons/godot-xr-tools/effects/vignette.tres")
var auto_first = true
var fade_delay = 0.0
var origin_node = null
var last_origin_basis : Basis
var last_location : Vector3
@onready var auto_rotation_limit_rad = deg_to_rad(auto_rotation_limit)
func set_radius(new_radius : float) -> void:
radius = new_radius
if is_inside_tree():
_update_radius()
func _update_radius() -> void:
if radius < 1.0:
if material:
material.set_shader_parameter("radius", radius * sqrt(2))
$Mesh.visible = true
else:
$Mesh.visible = false
func set_fade(new_fade : float) -> void:
fade = new_fade
if is_inside_tree():
_update_fade()
func _update_fade() -> void:
if material:
material.set_shader_parameter("fade", fade)
func set_steps(new_steps : int) -> void:
steps = new_steps
if is_inside_tree():
_update_mesh()
func _update_mesh() -> void:
var vertices : PackedVector3Array
var indices : PackedInt32Array
vertices.resize(2 * steps)
indices.resize(6 * steps)
for i in steps:
var v : Vector3 = Vector3.RIGHT.rotated(Vector3.FORWARD, deg_to_rad((360.0 * i) / steps))
vertices[i] = v
vertices[steps+i] = v * 2.0
var off = i * 6
var i2 = ((i + 1) % steps)
indices[off + 0] = steps + i
indices[off + 1] = steps + i2
indices[off + 2] = i2
indices[off + 3] = steps + i
indices[off + 4] = i2
indices[off + 5] = i
# update our mesh
var arr_mesh = ArrayMesh.new()
var arr : Array
arr.resize(ArrayMesh.ARRAY_MAX)
arr[ArrayMesh.ARRAY_VERTEX] = vertices
arr[ArrayMesh.ARRAY_INDEX] = indices
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)
arr_mesh.custom_aabb = AABB(Vector3(-1.0, -1.0, -1.0), Vector3(1.0, 1.0, 1.0))
$Mesh.mesh = arr_mesh
$Mesh.set_surface_override_material(0, material)
func set_auto_adjust(new_auto_adjust : bool) -> void:
auto_adjust = new_auto_adjust
if is_inside_tree() and !Engine.is_editor_hint():
_update_auto_adjust()
func _update_auto_adjust() -> void:
# Turn process on if auto adjust is true.
# Note we don't turn it off here, we want to finish fading out the vignette if needed
if auto_adjust:
set_process(true)
func set_auto_rotation_limit(new_auto_rotation_limit : float) -> void:
auto_rotation_limit = new_auto_rotation_limit
auto_rotation_limit_rad = deg_to_rad(auto_rotation_limit)
# Add support for is_xr_class on XRTools classes
func is_xr_class(name : String) -> bool:
return name == "XRToolsVignette"
# Called when the node enters the scene tree for the first time.
func _ready():
if !Engine.is_editor_hint():
origin_node = XRHelpers.get_xr_origin(self)
_update_mesh()
_update_radius()
_update_fade()
_update_auto_adjust()
else:
set_process(false)
# Called on process
func _process(delta):
if Engine.is_editor_hint():
return
if !origin_node:
return
if !auto_adjust:
# set to true for next time this is enabled
auto_first = true
# We are done, turn off process
set_process(false)
return
if auto_first:
# first time we run process since starting, just record transform
last_origin_basis = origin_node.global_transform.basis
last_location = global_transform.origin
auto_first = false
return
# Get our delta transform
var delta_b = origin_node.global_transform.basis * last_origin_basis.inverse()
var delta_v = global_transform.origin - last_location
# Adjust radius based on rotation speed of our origin point (not of head movement).
# We convert our delta rotation to a quaterion.
# A quaternion represents a rotation around an angle.
var q = delta_b.get_rotation_quaternion()
# We get our angle from our w component and then adjust to get a
# rotation speed per second by dividing by delta
var angle = (2 * acos(q.w)) / delta
# Calculate what our radius should be for our rotation speed
var target_radius = 1.0
if auto_rotation_limit > 0:
target_radius = 1.0 - (
clamp(angle / auto_rotation_limit_rad, 0.0, 1.0) * (1.0 - auto_inner_radius))
# Now do the same for speed, this includes players physical speed but there
# isn't much we can do there.
if auto_velocity_limit > 0:
var velocity = delta_v.length() / delta
target_radius = min(target_radius, 1.0 - (
clamp(velocity / auto_velocity_limit, 0.0, 1.0) * (1.0 - auto_inner_radius)))
# if our radius is small then our current we apply it
if target_radius < radius:
set_radius(target_radius)
fade_delay = auto_fade_delay
elif fade_delay > 0.0:
fade_delay -= delta
else:
set_radius(clamp(radius + delta / auto_fade_out_factor, 0.0, 1.0))
last_origin_basis = origin_node.global_transform.basis
last_location = global_transform.origin
# This method verifies the vignette has a valid configuration.
# Specifically it checks the following:
# - XROrigin3D is a parent
# - XRCamera3D is our parent
func _get_configuration_warnings() -> PackedStringArray:
var warnings := PackedStringArray()
# Check the origin node
if !XRHelpers.get_xr_origin(self):
warnings.append("Parent node must be in a branch from XROrigin3D")
# check camera node
var parent = get_parent()
if !parent or !parent is XRCamera3D:
warnings.append("Parent node must be an XRCamera3D")
return warnings
@@ -0,0 +1 @@
uid://dpai27qonyr5
@@ -0,0 +1,34 @@
shader_type spatial;
render_mode depth_test_disabled, skip_vertex_transform, unshaded, cull_disabled;
uniform vec4 color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform float radius = 1.0;
uniform float fade = 0.05;
varying float dist;
void vertex() {
vec3 v = VERTEX;
dist = length(v);
// outer ring is 2.0, inner ring is 1.0, so this scales purely the inner ring
if (dist < 1.5) {
// Adjust by radius
dist = radius;
v *= dist;
// We don't know our eye center, projecting a center point in the distance gives us a good enough approximation
vec4 eye = PROJECTION_MATRIX * vec4(0.0, 0.0, 100.0, 1.0);
// and we offset our inner circle
v.xy += eye.xy / eye.z;
}
// looks like this is broken in Godot 4...
POSITION = vec4(v, 1.0);
}
void fragment() {
ALBEDO = color.rgb;
ALPHA = clamp((dist - radius) / fade, 0.0, 1.0);
}
@@ -0,0 +1 @@
uid://bcmamo5d8n7ml
@@ -0,0 +1,10 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://cesiqdvdfojle"]
[ext_resource type="Shader" path="res://addons/godot-xr-tools/effects/vignette.gdshader" id="1_x02h0"]
[resource]
render_priority = 0
shader = ExtResource("1_x02h0")
shader_parameter/color = Color(0, 0, 0, 1)
shader_parameter/radius = 0.2
shader_parameter/fade = 0.05
@@ -0,0 +1,27 @@
[gd_scene load_steps=4 format=3 uid="uid://cc6ngdqie8o8c"]
[ext_resource type="Script" path="res://addons/godot-xr-tools/effects/vignette.gd" id="1"]
[ext_resource type="Material" uid="uid://cesiqdvdfojle" path="res://addons/godot-xr-tools/effects/vignette.tres" id="2_djtaj"]
[sub_resource type="ArrayMesh" id="ArrayMesh_yyajy"]
_surfaces = [{
"aabb": AABB(-2, -2, 0, 4, 4, 1e-05),
"format": 4097,
"index_count": 192,
"index_data": PackedByteArray(32, 0, 33, 0, 1, 0, 32, 0, 1, 0, 0, 0, 33, 0, 34, 0, 2, 0, 33, 0, 2, 0, 1, 0, 34, 0, 35, 0, 3, 0, 34, 0, 3, 0, 2, 0, 35, 0, 36, 0, 4, 0, 35, 0, 4, 0, 3, 0, 36, 0, 37, 0, 5, 0, 36, 0, 5, 0, 4, 0, 37, 0, 38, 0, 6, 0, 37, 0, 6, 0, 5, 0, 38, 0, 39, 0, 7, 0, 38, 0, 7, 0, 6, 0, 39, 0, 40, 0, 8, 0, 39, 0, 8, 0, 7, 0, 40, 0, 41, 0, 9, 0, 40, 0, 9, 0, 8, 0, 41, 0, 42, 0, 10, 0, 41, 0, 10, 0, 9, 0, 42, 0, 43, 0, 11, 0, 42, 0, 11, 0, 10, 0, 43, 0, 44, 0, 12, 0, 43, 0, 12, 0, 11, 0, 44, 0, 45, 0, 13, 0, 44, 0, 13, 0, 12, 0, 45, 0, 46, 0, 14, 0, 45, 0, 14, 0, 13, 0, 46, 0, 47, 0, 15, 0, 46, 0, 15, 0, 14, 0, 47, 0, 48, 0, 16, 0, 47, 0, 16, 0, 15, 0, 48, 0, 49, 0, 17, 0, 48, 0, 17, 0, 16, 0, 49, 0, 50, 0, 18, 0, 49, 0, 18, 0, 17, 0, 50, 0, 51, 0, 19, 0, 50, 0, 19, 0, 18, 0, 51, 0, 52, 0, 20, 0, 51, 0, 20, 0, 19, 0, 52, 0, 53, 0, 21, 0, 52, 0, 21, 0, 20, 0, 53, 0, 54, 0, 22, 0, 53, 0, 22, 0, 21, 0, 54, 0, 55, 0, 23, 0, 54, 0, 23, 0, 22, 0, 55, 0, 56, 0, 24, 0, 55, 0, 24, 0, 23, 0, 56, 0, 57, 0, 25, 0, 56, 0, 25, 0, 24, 0, 57, 0, 58, 0, 26, 0, 57, 0, 26, 0, 25, 0, 58, 0, 59, 0, 27, 0, 58, 0, 27, 0, 26, 0, 59, 0, 60, 0, 28, 0, 59, 0, 28, 0, 27, 0, 60, 0, 61, 0, 29, 0, 60, 0, 29, 0, 28, 0, 61, 0, 62, 0, 30, 0, 61, 0, 30, 0, 29, 0, 62, 0, 63, 0, 31, 0, 62, 0, 31, 0, 30, 0, 63, 0, 32, 0, 0, 0, 63, 0, 0, 0, 31, 0),
"primitive": 3,
"vertex_count": 64,
"vertex_data": PackedByteArray(0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 190, 20, 123, 63, 194, 197, 71, 190, 0, 0, 0, 0, 94, 131, 108, 63, 22, 239, 195, 190, 0, 0, 0, 0, 49, 219, 84, 63, 218, 57, 14, 191, 0, 0, 0, 0, 243, 4, 53, 63, 243, 4, 53, 191, 0, 0, 0, 0, 218, 57, 14, 63, 49, 219, 84, 191, 0, 0, 0, 0, 21, 239, 195, 62, 94, 131, 108, 191, 0, 0, 0, 0, 196, 197, 71, 62, 190, 20, 123, 191, 0, 0, 0, 0, 46, 189, 59, 179, 0, 0, 128, 191, 0, 0, 0, 0, 194, 197, 71, 190, 190, 20, 123, 191, 0, 0, 0, 0, 20, 239, 195, 190, 95, 131, 108, 191, 0, 0, 0, 0, 217, 57, 14, 191, 50, 219, 84, 191, 0, 0, 0, 0, 243, 4, 53, 191, 243, 4, 53, 191, 0, 0, 0, 0, 50, 219, 84, 191, 217, 57, 14, 191, 0, 0, 0, 0, 94, 131, 108, 191, 23, 239, 195, 190, 0, 0, 0, 0, 191, 20, 123, 191, 193, 197, 71, 190, 0, 0, 0, 0, 0, 0, 128, 191, 46, 189, 187, 51, 0, 0, 0, 0, 191, 20, 123, 191, 189, 197, 71, 62, 0, 0, 0, 0, 94, 131, 108, 191, 21, 239, 195, 62, 0, 0, 0, 0, 48, 219, 84, 191, 219, 57, 14, 63, 0, 0, 0, 0, 244, 4, 53, 191, 242, 4, 53, 63, 0, 0, 0, 0, 221, 57, 14, 191, 47, 219, 84, 63, 0, 0, 0, 0, 26, 239, 195, 190, 94, 131, 108, 63, 0, 0, 0, 0, 198, 197, 71, 190, 190, 20, 123, 63, 0, 0, 0, 0, 46, 222, 76, 50, 0, 0, 128, 63, 0, 0, 0, 0, 200, 197, 71, 62, 190, 20, 123, 63, 0, 0, 0, 0, 27, 239, 195, 62, 93, 131, 108, 63, 0, 0, 0, 0, 215, 57, 14, 63, 51, 219, 84, 63, 0, 0, 0, 0, 242, 4, 53, 63, 245, 4, 53, 63, 0, 0, 0, 0, 49, 219, 84, 63, 219, 57, 14, 63, 0, 0, 0, 0, 95, 131, 108, 63, 21, 239, 195, 62, 0, 0, 0, 0, 191, 20, 123, 63, 188, 197, 71, 62, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 190, 20, 251, 63, 194, 197, 199, 190, 0, 0, 0, 0, 94, 131, 236, 63, 22, 239, 67, 191, 0, 0, 0, 0, 49, 219, 212, 63, 218, 57, 142, 191, 0, 0, 0, 0, 243, 4, 181, 63, 243, 4, 181, 191, 0, 0, 0, 0, 218, 57, 142, 63, 49, 219, 212, 191, 0, 0, 0, 0, 21, 239, 67, 63, 94, 131, 236, 191, 0, 0, 0, 0, 196, 197, 199, 62, 190, 20, 251, 191, 0, 0, 0, 0, 46, 189, 187, 179, 0, 0, 0, 192, 0, 0, 0, 0, 194, 197, 199, 190, 190, 20, 251, 191, 0, 0, 0, 0, 20, 239, 67, 191, 95, 131, 236, 191, 0, 0, 0, 0, 217, 57, 142, 191, 50, 219, 212, 191, 0, 0, 0, 0, 243, 4, 181, 191, 243, 4, 181, 191, 0, 0, 0, 0, 50, 219, 212, 191, 217, 57, 142, 191, 0, 0, 0, 0, 94, 131, 236, 191, 23, 239, 67, 191, 0, 0, 0, 0, 191, 20, 251, 191, 193, 197, 199, 190, 0, 0, 0, 0, 0, 0, 0, 192, 46, 189, 59, 52, 0, 0, 0, 0, 191, 20, 251, 191, 189, 197, 199, 62, 0, 0, 0, 0, 94, 131, 236, 191, 21, 239, 67, 63, 0, 0, 0, 0, 48, 219, 212, 191, 219, 57, 142, 63, 0, 0, 0, 0, 244, 4, 181, 191, 242, 4, 181, 63, 0, 0, 0, 0, 221, 57, 142, 191, 47, 219, 212, 63, 0, 0, 0, 0, 26, 239, 67, 191, 94, 131, 236, 63, 0, 0, 0, 0, 198, 197, 199, 190, 190, 20, 251, 63, 0, 0, 0, 0, 46, 222, 204, 50, 0, 0, 0, 64, 0, 0, 0, 0, 200, 197, 199, 62, 190, 20, 251, 63, 0, 0, 0, 0, 27, 239, 67, 63, 93, 131, 236, 63, 0, 0, 0, 0, 215, 57, 142, 63, 51, 219, 212, 63, 0, 0, 0, 0, 242, 4, 181, 63, 245, 4, 181, 63, 0, 0, 0, 0, 49, 219, 212, 63, 219, 57, 142, 63, 0, 0, 0, 0, 95, 131, 236, 63, 21, 239, 67, 63, 0, 0, 0, 0, 191, 20, 251, 63, 188, 197, 199, 62, 0, 0, 0, 0)
}]
custom_aabb = AABB(-1, -1, -1, 1, 1, 1)
[node name="Vignette" type="Node3D"]
script = ExtResource("1")
[node name="Mesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1)
visible = false
cast_shadow = 0
ignore_occlusion_culling = true
mesh = SubResource("ArrayMesh_yyajy")
surface_material_override/0 = ExtResource("2_djtaj")