From 5e213f3dba1ed9300b826ddbaf01ac52ae7e8dec Mon Sep 17 00:00:00 2001 From: Spencer Killen Date: Sun, 12 Nov 2023 11:45:10 -0700 Subject: [PATCH] time warp effect --- godot/TAS_system/TAS_System.cs | 31 ++++++++ godot/UI/TAS UI/AdvanceButton.cs | 5 +- godot/UI/TAS UI/Label2.gd | 4 + godot/UI/TAS UI/RegressButton.cs | 5 +- godot/UI/TAS UI/TAS UI.tscn | 16 +++- godot/tests/control_scheme/screen_shader.gd | 19 +++++ .../control_scheme/screen_shader.gdshader | 34 +++++++++ .../control_scheme/test_basic_controls.tscn | 76 ++++++++++++++----- 8 files changed, 167 insertions(+), 23 deletions(-) create mode 100644 godot/UI/TAS UI/Label2.gd create mode 100644 godot/tests/control_scheme/screen_shader.gd create mode 100644 godot/tests/control_scheme/screen_shader.gdshader diff --git a/godot/TAS_system/TAS_System.cs b/godot/TAS_system/TAS_System.cs index 9973ee8..e0ac6ae 100644 --- a/godot/TAS_system/TAS_System.cs +++ b/godot/TAS_system/TAS_System.cs @@ -8,6 +8,15 @@ public partial class TAS_System : Node private double _timeSinceLastFrame; private int _currentFrame = 0; private int _lastAdvancedFrame = 0; + [Export] + public double min_speed = 1.0; + [Export] + public double max_speed = 10.0; + // Number of ms passed while speeding up + [Export] + public double speed = 0.0; + [Export] + public double exp_speed_base = 1.05; public double FrameLength { @@ -73,6 +82,9 @@ public partial class TAS_System : Node [Signal] public delegate void FramesResetEventHandler(); + [Signal] + public delegate void SpeedChangeEventHandler(float speed); + public void StartIncrementingFrames() { @@ -109,6 +121,25 @@ public partial class TAS_System : Node return framesAdvanced; } + public int AdvanceWithSpeedup(double time_delta) { + speed += time_delta; + speed = Math.Clamp(speed, min_speed, max_speed); + EmitSignal(SignalName.SpeedChange, speed); + return Advance((int)Math.Pow(exp_speed_base, speed)); + } + + public int RegressWithSpeedup(double time_delta) { + speed += time_delta; + speed = Math.Clamp(speed, min_speed, max_speed); + EmitSignal(SignalName.SpeedChange, speed); + return Regress((int)Math.Pow(exp_speed_base, speed)); + } + + public void ResetSpeedup() { + speed = 0.0; + EmitSignal(SignalName.SpeedChange, speed); + } + // Returns how many frames it could successfully regress public int Regress(int numFrames) { diff --git a/godot/UI/TAS UI/AdvanceButton.cs b/godot/UI/TAS UI/AdvanceButton.cs index 5024ba4..6a365ca 100644 --- a/godot/UI/TAS UI/AdvanceButton.cs +++ b/godot/UI/TAS UI/AdvanceButton.cs @@ -13,7 +13,7 @@ public partial class AdvanceButton : Button this.Pressed += () => { TAS.Advance(1); }; this.ButtonDown += () => { this.isButtonPressed = true; }; - this.ButtonUp += () => { this.isButtonPressed = false; }; + this.ButtonUp += () => { this.isButtonPressed = false; TAS.ResetSpeedup(); }; } // Called every frame. 'delta' is the elapsed time since the previous frame. @@ -22,6 +22,7 @@ public partial class AdvanceButton : Button if (TAS.AdvancedFramesRemaining == 0) { this.Disabled = true; + TAS.ResetSpeedup(); this.isButtonPressed = false; } else @@ -30,7 +31,7 @@ public partial class AdvanceButton : Button if (this.isButtonPressed) { - TAS.Advance(1); + TAS.AdvanceWithSpeedup(delta); } } } diff --git a/godot/UI/TAS UI/Label2.gd b/godot/UI/TAS UI/Label2.gd new file mode 100644 index 0000000..58b025f --- /dev/null +++ b/godot/UI/TAS UI/Label2.gd @@ -0,0 +1,4 @@ +extends Label + +func _process(delta): + text = "Speed: " + str(TAS_System.speed) diff --git a/godot/UI/TAS UI/RegressButton.cs b/godot/UI/TAS UI/RegressButton.cs index 086b4b0..908a591 100644 --- a/godot/UI/TAS UI/RegressButton.cs +++ b/godot/UI/TAS UI/RegressButton.cs @@ -15,7 +15,7 @@ public partial class RegressButton : Button }; this.ButtonDown += () => { this.isButtonPressed = true; TAS.StopIncrementingFrames(); }; - this.ButtonUp += () => { this.isButtonPressed = false; }; + this.ButtonUp += () => { this.isButtonPressed = false; TAS.ResetSpeedup(); }; } public virtual void OnFrameIncremented(int newFrame) @@ -29,6 +29,7 @@ public partial class RegressButton : Button if (TAS.CurrentFrame == 0) { this.Disabled = true; + TAS.ResetSpeedup(); this.isButtonPressed = false; } else @@ -37,7 +38,7 @@ public partial class RegressButton : Button if (this.isButtonPressed) { - TAS.Regress(1); + TAS.RegressWithSpeedup(delta); } } } diff --git a/godot/UI/TAS UI/TAS UI.tscn b/godot/UI/TAS UI/TAS UI.tscn index afbe79f..dbdee21 100644 --- a/godot/UI/TAS UI/TAS UI.tscn +++ b/godot/UI/TAS UI/TAS UI.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=7 format=3 uid="uid://b1uf31ed6h0ir"] +[gd_scene load_steps=8 format=3 uid="uid://b1uf31ed6h0ir"] [ext_resource type="Script" path="res://UI/TAS UI/CurrentFrameLabel.cs" id="1_27u4w"] [ext_resource type="Script" path="res://UI/TAS UI/RegressButton.cs" id="2_fhmsa"] +[ext_resource type="Script" path="res://UI/TAS UI/Label2.gd" id="2_otida"] [ext_resource type="Script" path="res://UI/TAS UI/AdvanceButton.cs" id="3_0ti6q"] [ext_resource type="Script" path="res://UI/TAS UI/StopIncrementButton.cs" id="4_4gd4c"] [ext_resource type="Script" path="res://UI/TAS UI/StartIncrementButton.cs" id="5_5af83"] @@ -36,6 +37,19 @@ grow_vertical = 0 text = "Current Frame: 0" script = ExtResource("1_27u4w") +[node name="Label2" type="Label" parent="DEBUG"] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 2.0 +offset_top = -55.0 +offset_right = 201.0 +offset_bottom = -29.0 +grow_vertical = 0 +text = "Current Frame: 0" +script = ExtResource("2_otida") + [node name="FrameButtons" type="Control" parent="."] layout_mode = 1 anchors_preset = 7 diff --git a/godot/tests/control_scheme/screen_shader.gd b/godot/tests/control_scheme/screen_shader.gd new file mode 100644 index 0000000..32657f3 --- /dev/null +++ b/godot/tests/control_scheme/screen_shader.gd @@ -0,0 +1,19 @@ +extends Control + + +@onready var shader: ShaderMaterial = $ColorRect.material +@onready var amount = TAS_System.speed +@onready var target_amount = TAS_System.speed + + +func _ready(): + set_amount(TAS_System.speed) + TAS_System.SpeedChange.connect(set_amount) + + +func set_amount(speed: float): + target_amount = (speed - TAS_System.min_speed) / (TAS_System.max_speed - TAS_System.min_speed) + +func _process(_delta): + amount = lerp(amount, target_amount, 0.1) + shader.set_shader_parameter("amount", amount*3) diff --git a/godot/tests/control_scheme/screen_shader.gdshader b/godot/tests/control_scheme/screen_shader.gdshader new file mode 100644 index 0000000..66f7c18 --- /dev/null +++ b/godot/tests/control_scheme/screen_shader.gdshader @@ -0,0 +1,34 @@ +// https://github.com/ttencate/blur_godot4/blob/main/Blur.gdshader + +shader_type canvas_item; + +// Radius that the shader was designed for. +const float DEFAULT_RADIUS = 10.000000; + +// Unit vector: (1, 0) or (0, 1) +uniform vec2 step = vec2(0, 1); +// Desired blur radius. +uniform float radius = 10.000000; +uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest; +uniform sampler2D darken_curve : source_color, repeat_disable; +uniform float amount; + +void fragment() { + vec2 s = radius / DEFAULT_RADIUS * step / vec2(textureSize(screen_texture, 0)); + COLOR.rgb = + 0.011194727 * texture(screen_texture, SCREEN_UV - 10.000000000 * s).rgb + + 0.039368696 * texture(screen_texture, SCREEN_UV - 8.415809477 * s).rgb + + 0.071308558 * texture(screen_texture, SCREEN_UV - 6.435363708 * s).rgb + + 0.110237219 * texture(screen_texture, SCREEN_UV - 4.455121108 * s).rgb + + 0.145451038 * texture(screen_texture, SCREEN_UV - 2.475020813 * s).rgb + + 0.163798995 * texture(screen_texture, SCREEN_UV - 0.495000167 * s).rgb + + 0.157439298 * texture(screen_texture, SCREEN_UV + 1.485004498 * s).rgb + + 0.129158204 * texture(screen_texture, SCREEN_UV + 3.465057055 * s).rgb + + 0.090434685 * texture(screen_texture, SCREEN_UV + 5.445220765 * s).rgb + + 0.054043977 * texture(screen_texture, SCREEN_UV + 7.425557483 * s).rgb + + 0.027564604 * texture(screen_texture, SCREEN_UV + 9.406126897 * s).rgb; + COLOR.a = 1.0; + float darken = 1.0-distance(SCREEN_UV, vec2(0.5)); + darken = mix(darken, .5, -amount); + COLOR.rgb = min(COLOR.rgb, texture(darken_curve, vec2(darken)).rgb); +} \ No newline at end of file diff --git a/godot/tests/control_scheme/test_basic_controls.tscn b/godot/tests/control_scheme/test_basic_controls.tscn index 7ad8a34..93c2a65 100644 --- a/godot/tests/control_scheme/test_basic_controls.tscn +++ b/godot/tests/control_scheme/test_basic_controls.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=9 format=3 uid="uid://70bb2yncbl"] +[gd_scene load_steps=14 format=3 uid="uid://70bb2yncbl"] [ext_resource type="PackedScene" uid="uid://bua7f25rpewkp" path="res://small_room.glb" id="1_2ticn"] [ext_resource type="PackedScene" uid="uid://drmb4sitb74fx" path="res://control_scheme/controller.tscn" id="2_dcvuq"] @@ -7,39 +7,79 @@ [ext_resource type="PackedScene" uid="uid://cx4ohbn84hmc3" path="res://cake.tscn" id="5_udc7s"] [ext_resource type="PackedScene" uid="uid://cfpiau12q3fut" path="res://Objects/child/child.tscn" id="6_52mue"] [ext_resource type="PackedScene" uid="uid://dfkyytk42ecwk" path="res://Objects/igloo/igloo.tscn" id="7_ifsxo"] +[ext_resource type="Script" path="res://tests/control_scheme/screen_shader.gd" id="8_crgih"] +[ext_resource type="Shader" path="res://tests/control_scheme/screen_shader.gdshader" id="8_w6ylu"] -[sub_resource type="Environment" id="Environment_f0m14"] +[sub_resource type="Gradient" id="Gradient_iyif7"] +offsets = PackedFloat32Array(0.333333, 0.635088, 1) +colors = PackedColorArray(0, 0, 0.345098, 1, 0.968421, 0.968421, 0.979319, 1, 1, 1, 1, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_kxwvs"] +gradient = SubResource("Gradient_iyif7") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_fmv5l"] +shader = ExtResource("8_w6ylu") +shader_parameter/step = Vector2(1, 0) +shader_parameter/radius = 15.0 +shader_parameter/amount = -0.485 +shader_parameter/darken_curve = SubResource("GradientTexture1D_kxwvs") + +[sub_resource type="Environment" id="Environment_nytpg"] ambient_light_source = 2 ambient_light_color = Color(1, 1, 1, 1) -ambient_light_energy = 0.5 +glow_normalized = true +glow_bloom = 0.32 +volumetric_fog_enabled = true +volumetric_fog_density = 0.4 +volumetric_fog_emission = Color(0.462745, 0.866667, 1, 1) [node name="small_room" instance=ExtResource("1_2ticn")] -[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="2"] -environment = SubResource("Environment_f0m14") - -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="WorldEnvironment" index="0"] -transform = Transform3D(1, 0, 0, 0, 0.933762, 0.357895, 0, -0.357895, 0.933762, 0, 1.43864, 1.81738) - -[node name="controller" parent="." index="3" node_paths=PackedStringArray("camera", "initial_target") instance=ExtResource("2_dcvuq")] +[node name="controller" parent="." index="2" node_paths=PackedStringArray("camera", "initial_target") instance=ExtResource("2_dcvuq")] camera = NodePath("../Camera3D") initial_target = NodePath("../grape") -[node name="grape" parent="." index="4" instance=ExtResource("3_gijly")] +[node name="grape" parent="." index="3" instance=ExtResource("3_gijly")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.56762, 0.385236) -[node name="grape2" parent="." index="5" instance=ExtResource("3_gijly")] +[node name="grape2" parent="." index="4" instance=ExtResource("3_gijly")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.115958, 1.77839, -0.189013) -[node name="TAS UI" parent="." index="6" instance=ExtResource("4_8yatx")] - -[node name="Camera3D" type="Camera3D" parent="." index="7"] +[node name="Camera3D" type="Camera3D" parent="." index="5"] current = true -[node name="cake" parent="." index="8" instance=ExtResource("5_udc7s")] +[node name="cake" parent="." index="6" instance=ExtResource("5_udc7s")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.45077, 0) -[node name="child" parent="." index="9" instance=ExtResource("6_52mue")] +[node name="child" parent="." index="7" instance=ExtResource("6_52mue")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2.93688) -[node name="igloo" parent="." index="10" instance=ExtResource("7_ifsxo")] +[node name="igloo" parent="." index="8" instance=ExtResource("7_ifsxo")] + +[node name="screen_shader" type="Control" parent="." index="9"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 +script = ExtResource("8_crgih") + +[node name="ColorRect" type="ColorRect" parent="screen_shader" index="0"] +material = SubResource("ShaderMaterial_fmv5l") +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 1 + +[node name="WorldEnvironment2" type="WorldEnvironment" parent="screen_shader" index="1"] +environment = SubResource("Environment_nytpg") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="screen_shader" index="2"] +transform = Transform3D(0.495368, 0.868683, -1.47631e-08, -0.635304, 0.362283, 0.682011, 0.592452, -0.337846, 0.731342, 0, 2.28, 1.03672) + +[node name="TAS UI" parent="." index="10" instance=ExtResource("4_8yatx")]