initial commit

This commit is contained in:
raa 2024-11-12 18:09:47 +01:00
commit 927a387756
238 changed files with 33853 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

View File

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/contentModel.xml
/projectSettingsUpdater.xml
/.idea.Karrot Starter Template.iml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1 @@
Karrot Starter Template

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="GdSdk Master" type="GdScript">
<properties path="$USER_HOME$/.cache/JetBrains/Rider2024.2/projects/.idea.karrot starter template.b2e532f7/sdk/GdSdk Master" version="Master" date="2024-06-01T15:14:16.000+02:00" />
<CLASSES />
<JAVADOC />
<SOURCES>
<root url="file://$USER_HOME$/.cache/JetBrains/Rider2024.2/projects/.idea.karrot starter template.b2e532f7/sdk/GdSdk Master" />
</SOURCES>
</library>
</component>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,20 @@
[gd_resource type="StandardMaterial3D" load_steps=6 format=3 uid="uid://dqla0ew3vkidw"]
[ext_resource type="Texture2D" uid="uid://xio2hyg54pq5" path="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_BaseColor.png" id="1_kv6au"]
[ext_resource type="Texture2D" uid="uid://b7kwylfnih7ys" path="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Emission.png" id="2_0gsej"]
[ext_resource type="Texture2D" uid="uid://cf3s5abr6nqbx" path="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Roughness.png" id="2_1xcsr"]
[ext_resource type="Texture2D" uid="uid://f3pmpp7caysw" path="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Metallic.png" id="2_fhho6"]
[ext_resource type="Texture2D" uid="uid://utrh1npj1bw7" path="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Normal.png" id="3_dxgwi"]
[resource]
resource_name = "Beta_HighLimbsGeoSG3"
cull_mode = 2
albedo_texture = ExtResource("1_kv6au")
metallic_texture = ExtResource("2_fhho6")
metallic_texture_channel = 2
roughness_texture = ExtResource("2_1xcsr")
emission_enabled = true
emission_energy_multiplier = 16.0
emission_texture = ExtResource("2_0gsej")
normal_enabled = true
normal_texture = ExtResource("3_dxgwi")

View File

@ -0,0 +1,17 @@
[gd_resource type="StandardMaterial3D" load_steps=5 format=3 uid="uid://b06cpt27xaioe"]
[ext_resource type="Texture2D" uid="uid://ckce81gur32lv" path="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_BaseColor.png" id="1_yejvp"]
[ext_resource type="Texture2D" uid="uid://bmrmlr2q1oi0b" path="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Roughness.png" id="2_73ebm"]
[ext_resource type="Texture2D" uid="uid://ju2kd17d8law" path="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Metallic.png" id="2_iejs5"]
[ext_resource type="Texture2D" uid="uid://v00gcquwugxr" path="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Normal.png" id="3_ly1qf"]
[resource]
resource_name = "Beta_Joints_MAT1"
cull_mode = 2
albedo_texture = ExtResource("1_yejvp")
metallic = 1.0
metallic_texture = ExtResource("2_iejs5")
roughness_texture = ExtResource("2_73ebm")
roughness_texture_channel = 1
normal_enabled = true
normal_texture = ExtResource("3_ly1qf")

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://xio2hyg54pq5"
path="res://.godot/imported/Beta_HighLimbsGeoSG3_BaseColor.png-d760cfb9c20cabeb616bc226ec3788b4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_BaseColor.png"
dest_files=["res://.godot/imported/Beta_HighLimbsGeoSG3_BaseColor.png-d760cfb9c20cabeb616bc226ec3788b4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b7kwylfnih7ys"
path.s3tc="res://.godot/imported/Beta_HighLimbsGeoSG3_Emission.png-6ee1e3a763a172015a47eca0aad475fb.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Emission.png"
dest_files=["res://.godot/imported/Beta_HighLimbsGeoSG3_Emission.png-6ee1e3a763a172015a47eca0aad475fb.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://f3pmpp7caysw"
path="res://.godot/imported/Beta_HighLimbsGeoSG3_Metallic.png-9d0d7559fc3177a7315d32389633ebd7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Metallic.png"
dest_files=["res://.godot/imported/Beta_HighLimbsGeoSG3_Metallic.png-9d0d7559fc3177a7315d32389633ebd7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://utrh1npj1bw7"
path="res://.godot/imported/Beta_HighLimbsGeoSG3_Normal.png-944980623f8740a875c1db7846932ae0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Normal.png"
dest_files=["res://.godot/imported/Beta_HighLimbsGeoSG3_Normal.png-944980623f8740a875c1db7846932ae0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=1
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=1
roughness/src_normal="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Normal.png"
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cf3s5abr6nqbx"
path="res://.godot/imported/Beta_HighLimbsGeoSG3_Roughness.png-44849828e6e79be4c21cd64e6fb86ff1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_HighLimbsGeoSG3_Roughness.png"
dest_files=["res://.godot/imported/Beta_HighLimbsGeoSG3_Roughness.png-44849828e6e79be4c21cd64e6fb86ff1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ckce81gur32lv"
path="res://.godot/imported/Beta_Joints_MAT1_BaseColor.png-66990c17af16f2363ecb17bfac6362c3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_BaseColor.png"
dest_files=["res://.godot/imported/Beta_Joints_MAT1_BaseColor.png-66990c17af16f2363ecb17bfac6362c3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ju2kd17d8law"
path="res://.godot/imported/Beta_Joints_MAT1_Metallic.png-6d1f215ca6d061345355b0dd257d1339.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Metallic.png"
dest_files=["res://.godot/imported/Beta_Joints_MAT1_Metallic.png-6d1f215ca6d061345355b0dd257d1339.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://v00gcquwugxr"
path="res://.godot/imported/Beta_Joints_MAT1_Normal.png-74ec659e2e7975b2b711b9f1055131f3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Normal.png"
dest_files=["res://.godot/imported/Beta_Joints_MAT1_Normal.png-74ec659e2e7975b2b711b9f1055131f3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=1
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=1
roughness/src_normal="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Normal.png"
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bmrmlr2q1oi0b"
path="res://.godot/imported/Beta_Joints_MAT1_Roughness.png-6fde9432ade91a326cd4b1c087ca0443.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Characters/XBot/Textures/Beta_Joints_MAT1_Roughness.png"
dest_files=["res://.godot/imported/Beta_Joints_MAT1_Roughness.png-6fde9432ade91a326cd4b1c087ca0443.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
Assets/Textures/damage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmfq4ni7ai3rb"
path="res://.godot/imported/damage.png-f76f817e57d6f3460b78f4d6aeb0ca27.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Textures/damage.png"
dest_files=["res://.godot/imported/damage.png-f76f817e57d6f3460b78f4d6aeb0ca27.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

BIN
Assets/Textures/grid.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cuylq7ede8ci6"
path.s3tc="res://.godot/imported/grid.jpg-4a037e076510e53a721a467c57d60915.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://Assets/Textures/grid.jpg"
dest_files=["res://.godot/imported/grid.jpg-4a037e076510e53a721a467c57d60915.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@ -0,0 +1,61 @@
using System;
using Godot;
namespace KarrotStarterTemplate.Common.AnimNotifies;
[GlobalClass]
public partial class AnimNotify : Node
{
// Called when the node enters the scene tree for the first time.
[Export] public AnimationMixer animationPlayer { get; set; }
[Export] public AnimationTree animationTree { get; set; }
public Action<string, string> AnimationNotify;
public override void _Ready()
{
if (animationPlayer != null)
{
animationPlayer.AnimationStarted += OnAnimationStarted;
animationPlayer.AnimationFinished += OnAnimationFinished;
}
if (animationTree != null)
{
animationTree.AnimationStarted += OnAnimationStarted;
animationTree.AnimationFinished += OnAnimationFinished;
}
}
public override void _ExitTree()
{
if (animationPlayer != null)
{
animationPlayer.AnimationStarted -= OnAnimationStarted;
animationPlayer.AnimationFinished -= OnAnimationFinished;
}
if (animationTree != null)
{
animationTree.AnimationStarted -= OnAnimationStarted;
animationTree.AnimationFinished -= OnAnimationFinished;
}
}
private void OnAnimationFinished(StringName animname)
{
Notify("_" + animname, "finish");
}
private void OnAnimationStarted(StringName animname)
{
Notify("_" + animname, "start");
}
public void Notify(string id, string action)
{
AnimationNotify?.Invoke(id, action);
}
}

View File

@ -0,0 +1,134 @@
using System.Linq;
using Godot;
namespace KarrotStarterTemplate.Common.CameraController;
[GlobalClass]
public partial class CharacterCameraController : Node3D
{
[ExportCategory("Nodes")]
[Export] public Node3D characterToFollow { get; set; }
[ExportCategory("Properties")]
[ExportGroup("Mouse input")]
[Export] public bool enableInput = true;
[Export] public float mouseSensitivity { get; set; } = .5f;
[Export] public Vector2 cameraTiltLimit { get; set; } = new(-45f, 45f);
[ExportGroup("Player")]
[Export] public bool followPlayer = true;
[Export(PropertyHint.Range, "0, 1")] public float followDelay { get; set; } = .5f;
[Export] public bool rotatePlayer = true;
[Export(PropertyHint.Range, "0, 1")] public float rotateDelay { get; set; } = .5f;
private Camera3D _camera; // todo
private SpringArm3D _springArm;
private Vector2 _mouseInput = Vector2.Zero;
public Camera3D camera => _camera;
public SpringArm3D springArm => _springArm;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
if (Engine.IsEditorHint())
{
TopLevel = true;
return;
}
characterToFollow ??= (CharacterBody3D)GetParent();
_springArm = GetChildren().OfType<SpringArm3D>().First();
_camera = _springArm.GetChildren().OfType<Camera3D>().First();
GlobalPosition = characterToFollow.GlobalPosition;
// Input.SetMouseMode(Input.MouseModeEnum.Captured);
}
public override void _UnhandledInput(InputEvent @event)
{
if (Engine.IsEditorHint())
{
return;
}
if (!enableInput)
{
return;
}
if (@event is InputEventMouseMotion mouseMotion)
{
_mouseInput = -mouseMotion.Relative * mouseSensitivity;
}
}
public override void _PhysicsProcess(double delta)
{
if (Engine.IsEditorHint())
{
return;
}
if (followPlayer)
{
float weight = Mathf.Clamp(20 * (1 - followDelay) * (float)delta, 0,1 );
GlobalPosition = followDelay > 0 ? GlobalPosition.Lerp(characterToFollow.GlobalPosition, weight) : characterToFollow.GlobalPosition;
}
if (rotatePlayer)
{
float weight = Mathf.Clamp(20 * (1 - rotateDelay) * (float)delta, 0,1 );
Vector3 v = characterToFollow.GlobalRotation;
characterToFollow.GlobalRotation = new Vector3(v.X, Mathf.LerpAngle(v.Y, _springArm.GlobalRotation.Y, weight) , v.Z);
}
if (enableInput)
{
_springArm.Rotation += new Vector3(_mouseInput.Y * (float)delta, 0f, 0f);
Rotation += new Vector3(0f, _mouseInput.X * (float)delta, characterToFollow.GlobalPosition.Y);
var (x, y, z) = _springArm.RotationDegrees;
_springArm.RotationDegrees = new Vector3(Mathf.Clamp(x, cameraTiltLimit.X, cameraTiltLimit.Y), y, z);
_mouseInput = Vector2.Zero;
}
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
if (Engine.IsEditorHint())
{
return;
}
if (Input.IsActionJustPressed("click"))
{
var position2D = GetViewport().GetMousePosition();
var dropPlane = new Plane(new Vector3(0, 10f, 0), 0f);
var position3D =
dropPlane.IntersectsRay(camera.ProjectRayOrigin(position2D), camera.ProjectRayNormal(position2D));
if (position3D != null)
{
GD.Print(position3D);
DebugDraw3D.DrawSphere(position3D ?? Vector3.Zero, .5f, Colors.Aqua, 2f);
}
}
}
}
/*
TODO:
1. Zrobić enuma z presetami
if Input.is_action_pressed("click"):
var position2D = get_viewport().get_mouse_position()
var dropPlane = Plane(Vector3(0, 0, 10), z)
var position3D = dropPlane.intersects_ray(camera.project_ray_origin(position2D),camera.project_ray_normal(position2D))
print(position3D)
*/

View File

@ -0,0 +1,45 @@
using System.Linq;
using Godot;
namespace KarrotStarterTemplate.Common.CameraController;
[Tool]
public partial class CharacterCameraController : Node3D
{
public override string[] _GetConfigurationWarnings()
{
SpringArm3D checkSpringArm = GetChildren().OfType<SpringArm3D>().FirstOrDefault();
if (checkSpringArm == null)
{
return ["No SpringArm3D found"];
}
else
{
Camera3D checkCamera = checkSpringArm.GetChildren().OfType<Camera3D>().FirstOrDefault();
if (checkCamera == null)
{
return ["No Camera3D (inside camera) found"];
}
}
return [];
}
//
// public override void _Notification(int what)
// {
// switch ((long)what)
// {
// case NotificationChildOrderChanged:
// if (Engine.IsEditorHint())
// {
// UpdateConfigurationWarnings();
// }
//
// break;
// }
// }
}

View File

@ -0,0 +1,100 @@
using System;
using Godot;
using Playground.Common.CharacterMovement;
namespace KarrotStarterTemplate.Common.CharacterMovement;
[GlobalClass]
public partial class CharacterMovementController : Node
{
[Export] public CharacterBody3D characterBody { get; set; }
[Export] public CharacterMovementMode defaultMovementMode { get; set; }
[Export] public AnimationMixer animationTree { get; set; }
public CharacterMovementMode currentMovementMode { get; private set; }
private Vector3 _temporaryMovementDirection = Vector3.Zero;
public Vector2 blendspacePosition { get; private set; }
public override void _Ready()
{
currentMovementMode = defaultMovementMode;
characterBody ??= (CharacterBody3D)GetParent();
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _PhysicsProcess(double delta)
{
Vector3 velocity = characterBody.Velocity;
CharacterMovementMode v = currentMovementMode;
if (v.gravityScale != 0 && !characterBody.IsOnFloor())
{
velocity += characterBody.GetGravity() * (float)delta;
}
_temporaryMovementDirection = _temporaryMovementDirection.Normalized();
if (!_temporaryMovementDirection.IsZeroApprox())
{
// velocity.X = _temporaryMovementDirection.X * v.speed;
// velocity.Y += _temporaryMovementDirection.Y * v.speed;
// velocity.Z = _temporaryMovementDirection.Z * v.speed;
velocity = velocity.Lerp(_temporaryMovementDirection * v.speed, 3 * (float)delta);
if (v.rotationRate > 0)
{
Vector3 c = characterBody.GlobalRotation;
characterBody.GlobalRotation = new Vector3(0, Mathf.LerpAngle(c.Y, -Mathf.Atan2(velocity.X, -velocity.Z), Mathf.DegToRad(v.rotationRate) * (float)delta) , 0);
// characterBody.LookAt(characterBody.GlobalPosition + velocity);
}
}
else
{
if (velocity.Length() < .3)
{
velocity = velocity.MoveToward(new Vector3(0, velocity.Y, 0), 2 * (float)delta);
}
else
{
velocity = velocity.Lerp(new Vector3(0, velocity.Y, 0), 2 * (float)delta);
}
}
_temporaryMovementDirection = Vector3.Zero;
characterBody.Velocity = velocity;
characterBody.MoveAndSlide();
}
public override void _Process(double delta)
{
float x = characterBody.GlobalTransform.Basis.X.Dot(characterBody.Velocity);
float z = characterBody.GlobalTransform.Basis.Z.Dot(characterBody.Velocity) * -1;
blendspacePosition = blendspacePosition.MoveToward(new Vector2(x, z) , 4 * (float)delta * 1f);
}
public void SetMovementMode(CharacterMovementMode movementMode)
{
currentMovementMode = movementMode ?? defaultMovementMode;
}
public void AddMovementInput(Vector2 direction, float value)
{
AddMovementInput(new Vector3(direction.X, 0f, direction.Y), value);
}
public void AddMovementInput(Vector3 direction, float value)
{
if (currentMovementMode.ignoreUpDirection)
{
direction = new Vector3(direction.X, 0f, direction.Z);
}
_temporaryMovementDirection += direction * value;
}
}

View File

@ -0,0 +1,23 @@
using Godot;
namespace Playground.Common.CharacterMovement;
[GlobalClass]
public partial class CharacterMovementMode : Resource
{
[Export] public string Name;
[Export] public float speed { get; set; } = 5f;
[Export] public bool ignoreUpDirection { get; set; } = true;
[Export] public float acceleration { get; set; } = 1f;
[Export] public float deceleration { get; set; } = 1f;
[Export] public float gravityScale { get; set; } = 1f;
[Export] public float rotationRate { get; set; } = 360f;
}
/*
Max Step Height
Walkable Floor Angle
Ignore Base Rotation (rotate towards movement)
*/

View File

@ -0,0 +1,63 @@
using System.Threading.Tasks;
using Godot;
using KarrotStarterTemplate.Common.AnimNotifies;
using KarrotStarterTemplate.Common.CameraController;
using KarrotStarterTemplate.Common.CharacterMovement;
namespace KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
public abstract partial class BasePlayerState : State
{
[Export] public string transitionName { get; set; }
public CharacterMovementController characterMovement => basePlayerStateMachine.characterMovement;
protected BasePlayerStateMachine basePlayerStateMachine => (BasePlayerStateMachine)parentStateMachine;
protected CharacterBody3D characterBody => basePlayerStateMachine?.ownerCharacterBody;
protected CharacterCameraController cameraController => basePlayerStateMachine?.cameraController;
protected AnimationTree animationTree => basePlayerStateMachine?.animationTree;
protected AnimNotify animationNotify => basePlayerStateMachine?.animationNotify;
protected string transitionRequestPath => $"parameters/Transition/transition_request";
protected override Task OnEnter()
{
if (transitionName != null)
{
animationTree.Set(transitionRequestPath, transitionName);
animationNotify.AnimationNotify += OnAnimationNotify;
}
return Task.CompletedTask;
}
protected override Task OnExit()
{
animationNotify.AnimationNotify -= OnAnimationNotify;
return Task.CompletedTask;
}
protected override string OnCheckRelevance()
{
if (package.GetBool("roll"))
{
return "Roll";
}
if (!package.GetVector3("move_direction").IsZeroApprox())
{
if (package.GetBool("run"))
{
return "Run";
}
return "Walk";
}
return "Idle";
}
protected virtual void OnAnimationNotify(string name, string actionName)
{
}
}

View File

@ -0,0 +1,16 @@
using Godot;
using KarrotStarterTemplate.Common.AnimNotifies;
using KarrotStarterTemplate.Common.CameraController;
using KarrotStarterTemplate.Common.CharacterMovement;
namespace KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
public partial class BasePlayerStateMachine : StateMachine
{
[Export] public AnimationTree animationTree { get; set; }
[Export] public AnimNotify animationNotify { get; set; }
[Export] public CharacterMovementController characterMovement { get; set; }
[Export] public CharacterCameraController cameraController { get; set; }
}

View File

@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Godot;
using Playground.Common.CharacterMovement;
namespace KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
public partial class MovementBasePlayerState : BasePlayerState
{
// TODO
[Export] public string animationBlendPositionPath { get; set; } = "parameters/LocomotionBlendspace/blend_position";
[Export] public CharacterMovementMode movementMode { get; set; }
protected override Task OnEnter()
{
characterMovement.SetMovementMode(movementMode);
return base.OnEnter();
}
protected override void OnStateProcess(double delta)
{
base.OnStateProcess(delta);
animationTree.Set(animationBlendPositionPath, characterMovement.blendspacePosition);
}
protected override void OnStatePhysicsProcess(double delta)
{
characterMovement.AddMovementInput(cameraController.camera.GlobalBasis.Z, package.GetVector3("move_direction").Y);
characterMovement.AddMovementInput(cameraController.camera.GlobalBasis.X, package.GetVector3("move_direction").X);
// TODO: ?
// cameraController.rotatePlayer = !package.inputDirection.IsZeroApprox();
}
}

View File

@ -0,0 +1,85 @@
using System;
using System.Threading.Tasks;
using Godot;
namespace KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
public enum ERootMotionAnimationDirection
{
Character,
Camera,
Input,
}
public partial class RootMotionBasePlayerState : BasePlayerState
{
[Export] public ERootMotionAnimationDirection animationDirectionType { get; set; } =
ERootMotionAnimationDirection.Input;
[Export] public bool updateDirectionOnProcess { get; set; }
[Export] public ERootMotionAnimationDirection noInputDirectionTypeFallback { get; set; } =
ERootMotionAnimationDirection.Camera;
private Vector2 _blendPosition;
private Vector3 _velocity = Vector3.Zero;
private Vector3 _animationDirection = Vector3.Zero;
protected override Task OnEnter()
{
_animationDirection = GetRootMotionDirection();
return base.OnEnter();
}
protected override void OnStateProcess(double delta)
{
var (x, y, z) = animationTree.GetRootMotionPosition() / 2f;
_velocity += new Vector3(-x, y, -z);
base.OnStateProcess(delta);
}
protected override void OnStatePhysicsProcess(double delta)
{
if (updateDirectionOnProcess)
{
_animationDirection = GetRootMotionDirection();
}
if (_animationDirection != Vector3.Zero)
{
characterBody.GlobalRotation = new Vector3(0,
Mathf.LerpAngle(characterBody.GlobalRotation.Y,
-Mathf.Atan2(_animationDirection.X, -_animationDirection.Z), 10 * (float)delta), 0);
}
Quaternion rotationQuaternion = characterBody.Transform.Basis.GetRotationQuaternion();
characterBody.Velocity = rotationQuaternion.Normalized() * _velocity / (float)delta;
characterBody.MoveAndSlide();
_velocity = Vector3.Zero;
}
private Vector3 GetRootMotionDirection()
{
ERootMotionAnimationDirection temp = animationDirectionType;
if (temp == ERootMotionAnimationDirection.Input && package.GetVector3("move_direction").IsZeroApprox())
{
temp = noInputDirectionTypeFallback;
}
switch (temp)
{
case ERootMotionAnimationDirection.Character:
return Vector3.Zero;
case ERootMotionAnimationDirection.Camera:
return (-cameraController.camera.GlobalBasis.Z);
case ERootMotionAnimationDirection.Input:
return (cameraController.camera.GlobalBasis.Z * package.GetVector3("move_direction").Y) +
cameraController.camera.GlobalBasis.X * package.GetVector3("move_direction").X;
default:
throw new ArgumentOutOfRangeException();
}
}
}

View File

@ -0,0 +1,85 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Godot;
using Godot.Collections;
namespace KarrotStarterTemplate.Common.StateMachines;
public abstract partial class State : Node
{
[Export] public string id { get; private set; }
// [Export] public bool queueable { get; private set; }
[Export] public bool canTransitionToSelf { get; private set; }
[Export] public float minimumStateDuration { get; private set; }
public bool checkRelevance { get; protected set; } = true;
public bool queueRelevance { get; protected set; } = true;
protected List<string> statesInQueue = new();
private double _startTime;
protected float timeElapsed => (float)(Time.GetUnixTimeFromSystem() - _startTime);
protected StateMachine parentStateMachine;
public StateInputsPackage package => parentStateMachine.package;
public bool isActive => parentStateMachine?.currentState == this;
public bool isTransitioning => parentStateMachine?.currentState == this && parentStateMachine.isTransitioning;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
parentStateMachine = GetParent<StateMachine>();
}
protected abstract Task OnEnter();
protected abstract Task OnExit();
protected virtual void OnStateProcess(double delta) {}
protected virtual void OnStatePhysicsProcess(double delta) {}
protected virtual string OnCheckRelevance()
{
return null;
}
public async Task Enter()
{
_startTime = Time.GetUnixTimeFromSystem();
await OnEnter();
}
public async Task Exit()
{
statesInQueue.Clear();
await OnExit();
}
public void StateProcess(double delta)
{
OnStateProcess(delta);
}
public void StatePhysicsProcess(double delta)
{
OnStatePhysicsProcess(delta);
}
public string CheckRelevance()
{
string value = OnCheckRelevance();
if (timeElapsed <= (minimumStateDuration <= 0 ? 0.01f : minimumStateDuration) || !checkRelevance)
{
// if (queueRelevance && value != null && parentStateMachine.states[value].queueable)
// {
// statesInQueue.Add(value);
// }
return null;
}
// if (statesInQueue.Count > 0) return statesInQueue.Last();
return value;
}
}

View File

@ -0,0 +1,192 @@
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Godot;
using Godot.Collections;
namespace KarrotStarterTemplate.Common.StateMachines;
public class StateInputsPackage
{
/*
* Potrzebujemy:
* 1. Informacji jakie klawisze trzyma teraz gracz (np czy trzyma Shift, żeby przejść z Walk na Run) - done
* 2. Globalnych flag, które sie nie resetują (np. czy gracz wcisnął C i jest w trybie kucania, wciśnięcie C ponownie wyłącza flagę) - done
* 3. Informacji o tym czy w trakcie eventu gracz wcisnął dany klawisz (jeśli gracz kliknie atak w trakcie uniku to musimy zakolejkować to działanie
* 4. Wartości w wektorach (np inputDirection z WASD) - done
* 5. Informacji o tym, że skończyła się animacja, albo event z animnotify
*
* Gdy OnCheckRelevance coś zwraca, to nie powinniśmy przechodzić w ten state, tylko kolejkować to i sprawdzać czy aktualny stejt ma flagę "canExit" na true,
* wtedy odpalać ostatni dostępny state?
*/
private readonly Dictionary<string, Variant> _inputs = new Dictionary<string, Variant>();
public void Add(string key, Variant value)
{
_inputs[key] = value;
}
public void Clear(string key)
{
_inputs.Remove(key);
}
public Variant Get(string key)
{
if (_inputs.TryGetValue(key, out Variant value))
{
return value;
}
return new Variant();
}
public Vector3 GetVector3(string key)
{
if (_inputs.TryGetValue(key, out var value))
{
return value.AsVector3();
}
return Vector3.Zero;
}
public string GetString(string key)
{
if (_inputs.TryGetValue(key, out var value))
{
return value.AsString();
}
return "";
}
public bool GetBool(string key)
{
if (_inputs.TryGetValue(key, out var value))
{
return value.AsBool();
}
return false;
}
}
[GlobalClass]
public partial class StateMachine : Node
{
[Export] public Node3D owner { get; set; }
[Export] public State defaultState { get; set; }
[Export] public bool activateOnReady { get; set; }
public StateInputsPackage package { get; private set; } = new StateInputsPackage();
public State currentState { get; private set; }
public bool isTransitioning { get; private set; } = false;
public bool active => currentState != null;
public Dictionary<string, State> states { get; private set; } = new Dictionary<string, State>();
public CharacterBody3D ownerCharacterBody => (CharacterBody3D)owner;
// Called when the node enters the scene tree for the first time.
public override async void _Ready()
{
foreach (Node node in GetChildren())
{
if (node is State state)
{
states.Add(state.id, state);
}
}
if (activateOnReady)
{
await Activate();
}
}
public async Task Activate()
{
await TransitionToState(defaultState);
}
public async void Deactivate()
{
if (currentState != null)
{
await TransitionToState(null as State);
}
}
public override void _PhysicsProcess(double delta)
{
currentState?.StatePhysicsProcess(delta);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
if (currentState != null)
{
currentState.StateProcess(delta);
if (!isTransitioning)
{
string nextState = currentState.CheckRelevance();
if (nextState != null)
{
TransitionToState(nextState);
}
}
}
}
private Task<bool> TransitionToState(string stateId)
{
// if (currentState != null && currentState.id == stateId)
// {
// return Task.FromResult(false);
// }
return TransitionToState(states[stateId]);
}
private async Task<bool> TransitionToState(State state)
{
if (currentState == state && !state.canTransitionToSelf)
{
return false;
}
GD.Print("--");
GD.Print($"------------------------------------------");
GD.Print($"------Transitioning from {currentState?.id} to {state?.id}");
isTransitioning = true;
if (currentState != null)
{
await currentState.Exit();
}
if (state != null)
{
await state.Enter();
}
currentState = state;
GD.Print($"------Transition finished to {state?.id}");
GD.Print($"------------------------------------------");
GD.Print("--");
isTransitioning = false;
return true;
}
}

View File

@ -0,0 +1,20 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://b66garfwge15n"]
[ext_resource type="Shader" path="res://Content/Shaders/Grid.gdshader" id="1_ap05j"]
[ext_resource type="Texture2D" uid="uid://cuylq7ede8ci6" path="res://Assets/Textures/grid.jpg" id="2_nnk68"]
[resource]
render_priority = 0
shader = ExtResource("1_ap05j")
shader_parameter/albedo = Color(0.427493, 0.427493, 0.427493, 1)
shader_parameter/point_size = 0.0
shader_parameter/roughness = 0.7
shader_parameter/metallic_texture_channel = null
shader_parameter/specular = 0.5
shader_parameter/metallic = null
shader_parameter/uv1_blend_sharpness = 1.0
shader_parameter/uv1_scale = Vector3(0.5, 0.5, 0.5)
shader_parameter/uv1_offset = null
shader_parameter/uv2_scale = Vector3(1, 1, 1)
shader_parameter/uv2_offset = null
shader_parameter/texture_albedo = ExtResource("2_nnk68")

View File

@ -0,0 +1,21 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://f43wyn5nfiw7"]
[ext_resource type="Shader" path="res://Content/Shaders/Grid.gdshader" id="1_2ixob"]
[ext_resource type="Texture2D" uid="uid://cuylq7ede8ci6" path="res://Assets/Textures/grid.jpg" id="2_k80n0"]
[resource]
render_priority = 0
shader = ExtResource("1_2ixob")
shader_parameter/albedo = Color(0.86, 0.49364, 0.2494, 1)
shader_parameter/point_size = 0.0
shader_parameter/roughness = 0.5
shader_parameter/metallic_texture_channel = null
shader_parameter/specular = 0.5
shader_parameter/metallic = 0.0
shader_parameter/uv1_blend_sharpness = 1.0
shader_parameter/uv1_scale = Vector3(0.5, 0.5, 0.5)
shader_parameter/uv1_offset = Vector3(0, 0, 0)
shader_parameter/uv2_scale = Vector3(0, 0, 0)
shader_parameter/uv2_offset = Vector3(0, 0, 0)
shader_parameter/texture_albedo = ExtResource("2_k80n0")
shader_parameter/texture_roughness = ExtResource("2_k80n0")

View File

@ -0,0 +1,61 @@
[gd_scene load_steps=2 format=3 uid="uid://cb7dybtexd7ct"]
[ext_resource type="PackedScene" uid="uid://iv7fea1i36q5" path="res://Assets/Characters/XBot/XBot.blend" id="1_uyb6p"]
[node name="XBot2" instance=ExtResource("1_uyb6p")]
[node name="Skeleton3D" parent="XBot" index="0"]
bones/0/position = Vector3(1.41195e-07, -3.28627e-15, -2.75672e-08)
bones/1/position = Vector3(-7.72508e-08, 1.0427, 0.0155426)
bones/1/rotation = Quaternion(0.00645854, 1.75848e-08, -7.34395e-07, 0.999979)
bones/2/rotation = Quaternion(-0.0801557, -7.16735e-08, 4.83034e-07, 0.996782)
bones/3/rotation = Quaternion(-8.9407e-08, 1.13506e-13, -6.00325e-13, 1)
bones/4/rotation = Quaternion(0.0128857, -4.77102e-10, -3.70242e-08, 0.999917)
bones/5/rotation = Quaternion(-2.23517e-08, -3.17524e-14, -1.4333e-13, 1)
bones/6/rotation = Quaternion(5.21541e-08, 5.10703e-15, -1.03251e-14, 1)
bones/8/rotation = Quaternion(-0.484431, 0.570964, -0.526163, -0.403087)
bones/9/rotation = Quaternion(-0.0246159, 0.00256294, -0.103499, 0.994322)
bones/10/rotation = Quaternion(-2.97308e-08, -6.11244e-08, 1.81956e-08, 1)
bones/11/rotation = Quaternion(8.94058e-08, 2.92063e-06, 4.01323e-07, 1)
bones/12/rotation = Quaternion(0.252089, 0.0602818, -0.221704, 0.940035)
bones/13/rotation = Quaternion(1.4767e-06, -0.00117062, 9.48031e-07, 0.999999)
bones/14/rotation = Quaternion(-7.6201e-07, -0.00080769, -2.12422e-07, 1)
bones/16/rotation = Quaternion(9.02427e-07, -5.62793e-08, -1.69515e-07, 1)
bones/17/rotation = Quaternion(-6.3338e-06, 1.48183e-07, 6.19915e-08, 1)
bones/18/rotation = Quaternion(1.05446e-05, -1.43517e-07, 1.0114e-08, 1)
bones/20/rotation = Quaternion(9.62074e-07, -5.48842e-08, 6.67643e-08, 1)
bones/21/rotation = Quaternion(-2.11013e-06, 1.38136e-07, -1.72702e-07, 1)
bones/22/rotation = Quaternion(1.99061e-06, -2.92567e-07, 8.84756e-08, 1)
bones/24/rotation = Quaternion(-9.5298e-12, 3.53984e-08, -3.08995e-07, 1)
bones/25/rotation = Quaternion(-2.09246e-06, -5.66039e-09, -4.96512e-08, 1)
bones/26/rotation = Quaternion(2.09249e-06, 6.57403e-09, 1.21239e-07, 1)
bones/28/rotation = Quaternion(4.54762e-07, -4.06688e-08, 1.69908e-07, 1)
bones/29/rotation = Quaternion(-1.9801e-06, 1.23584e-07, -2.33413e-07, 1)
bones/30/rotation = Quaternion(5.64286e-06, -1.98771e-07, -2.5786e-07, 1)
bones/32/rotation = Quaternion(0.484423, 0.57097, -0.526162, 0.403089)
bones/33/rotation = Quaternion(-0.0246084, -0.00256157, 0.103504, 0.994321)
bones/34/rotation = Quaternion(5.71897e-07, -9.15815e-08, 4.9093e-08, 1)
bones/35/rotation = Quaternion(-1.17187e-07, 1.76792e-07, 7.68118e-07, 1)
bones/36/rotation = Quaternion(0.252061, -0.0601697, 0.221735, 0.940042)
bones/37/rotation = Quaternion(1.6883e-06, 0.0010432, -7.82669e-07, 1)
bones/38/rotation = Quaternion(9.62145e-07, 0.000745049, -4.07411e-07, 1)
bones/40/rotation = Quaternion(7.42193e-08, 1.71544e-07, 5.16462e-07, 1)
bones/41/rotation = Quaternion(3.60494e-07, -7.80742e-08, 3.62103e-07, 1)
bones/42/rotation = Quaternion(2.23444e-06, -7.40687e-08, -1.04556e-08, 1)
bones/44/rotation = Quaternion(-6.64825e-07, 1.26392e-07, -2.53789e-07, 1)
bones/45/rotation = Quaternion(3.9814e-06, -5.48769e-10, 4.05202e-07, 1)
bones/46/rotation = Quaternion(-4.04099e-06, -1.78094e-07, -4.33571e-07, 1)
bones/48/rotation = Quaternion(-1.56722e-06, 1.56186e-07, 1.00144e-07, 1)
bones/49/rotation = Quaternion(4.07075e-06, -1.20073e-07, 2.02915e-07, 1)
bones/50/rotation = Quaternion(-4.01121e-06, -3.12063e-07, -7.39729e-07, 1)
bones/52/rotation = Quaternion(1.08714e-06, 1.81099e-07, 1.28056e-07, 1)
bones/53/rotation = Quaternion(-5.96278e-06, -1.54125e-07, -3.24042e-07, 1)
bones/54/rotation = Quaternion(8.60433e-06, 4.56076e-07, 4.22384e-07, 1)
bones/56/rotation = Quaternion(-6.70988e-08, 0.0110284, 0.999939, -4.47224e-07)
bones/57/rotation = Quaternion(-0.0394318, -8.07853e-08, 8.95072e-09, 0.999222)
bones/58/rotation = Quaternion(0.460334, 2.46035e-08, -1.88488e-07, 0.887746)
bones/59/rotation = Quaternion(0.335241, 1.52652e-08, -9.76924e-08, 0.942132)
bones/61/rotation = Quaternion(-1.10238e-07, 0.0110182, 0.999939, -4.41362e-07)
bones/62/rotation = Quaternion(-0.0394102, -1.78917e-07, 1.8103e-08, 0.999223)
bones/63/rotation = Quaternion(0.460324, 1.23765e-08, -1.95442e-07, 0.887751)
bones/64/rotation = Quaternion(0.335241, 3.81901e-08, -1.40905e-07, 0.942132)

View File

@ -0,0 +1,310 @@
[gd_scene load_steps=6 format=3 uid="uid://egqb5kwxn5h5"]
[ext_resource type="Material" uid="uid://b66garfwge15n" path="res://Content/Materials/Grid.tres" id="1_l7v7s"]
[ext_resource type="Material" uid="uid://f43wyn5nfiw7" path="res://Content/Materials/GridProps.tres" id="2_bu80j"]
[ext_resource type="PackedScene" uid="uid://br57yle5ldjmr" path="res://Entities/Player/Player.tscn" id="3_4uxj6"]
[ext_resource type="PackedScene" uid="uid://iv7fea1i36q5" path="res://Assets/Characters/XBot/XBot.blend" id="3_p28sh"]
[ext_resource type="Environment" uid="uid://c1jlxnbw1vwp1" path="res://Resources/Misc/Environment.tres" id="3_xw2py"]
[node name="Playground" type="Node3D"]
[node name="Blockout" type="Node3D" parent="."]
[node name="CSGBox3D" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 15.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(20, 3, 53)
[node name="CSGBox3D3" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.5, 48)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(4, 3, 12)
[node name="CSGBox3D6" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 3.5, 17)
visible = false
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(18, 1, 14)
[node name="CSGBox3D2" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.5, 1.5, 22.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(7, 3, 3)
[node name="CSGBox3D7" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 1.5, 13.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(6, 3, 7)
[node name="CSGBox3D8" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1.5, 21.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(8, 3, 5)
[node name="CSGBox3D9" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1.5, 12.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(8, 3, 5)
[node name="CSGBox3D10" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 1.5, 17)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(1, 3, 4)
[node name="CSGBox3D4" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9, 2, 15.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(2, 4, 53)
[node name="CSGBox3D5" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 2, -0.5)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(2, 4, 21)
[node name="CSGBox3D11" type="CSGBox3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, -10)
material_override = ExtResource("1_l7v7s")
use_collision = true
size = Vector3(16, 4, 2)
[node name="CSGCylinder3D" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 1.25, 2)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D10" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 1.25, 9)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D11" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1.25, 9)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D6" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 1.25, 0)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D7" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 1.25, -6)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D8" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 1.25, -7)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D9" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 1.25, -4)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D12" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 1.25, -2)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7, 1.25, 4)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D3" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 1.25, -5)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D4" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1.25, -7)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="CSGCylinder3D5" type="CSGCylinder3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1.25, -3)
use_collision = true
radius = 0.3
height = 2.5
sides = 16
material = ExtResource("2_bu80j")
[node name="OmniLight3D" type="OmniLight3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6.4, 1.4, 26)
light_color = Color(1, 0, 0.9, 1)
shadow_enabled = true
shadow_blur = 2.0
omni_range = 3.0
[node name="OmniLight3D2" type="OmniLight3D" parent="Blockout"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.2, 1.4, 17)
light_color = Color(1, 0.53, 0.953, 1)
shadow_enabled = true
shadow_blur = 2.0
omni_range = 3.0
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = ExtResource("3_xw2py")
[node name="Player" parent="." instance=ExtResource("3_4uxj6")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, -3)
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(-0.506236, -0.711106, 0.487907, -0.183013, 0.641456, 0.74501, -0.842752, 0.287858, -0.45487, 0, 0, 0)
light_indirect_energy = 2.0
shadow_enabled = true
shadow_bias = 0.05
shadow_blur = 0.5
[node name="XBot2" parent="." instance=ExtResource("3_p28sh")]
transform = Transform3D(-0.707107, 0, 0.707107, 0, 1, 0, -0.707107, 0, -0.707107, -5.1, 0, 6)
[node name="Skeleton3D" parent="XBot2/XBot" index="0"]
bones/1/rotation = Quaternion(0.00645836, 1.61788e-09, 2.50506e-07, 0.999979)
bones/1/scale = Vector3(1, 1, 1)
bones/2/rotation = Quaternion(-0.0801557, 2.49493e-14, -2.48068e-07, 0.996782)
bones/4/rotation = Quaternion(0.0128857, -4.77102e-10, -3.70241e-08, 0.999917)
bones/8/rotation = Quaternion(-0.484431, 0.570964, -0.526164, -0.403087)
bones/8/scale = Vector3(1, 1, 1)
bones/9/rotation = Quaternion(-0.024616, 0.00256251, -0.103499, 0.994322)
bones/9/scale = Vector3(1, 1, 1)
bones/12/rotation = Quaternion(0.253284, 0.0616187, -0.22821, 0.938067)
bones/13/rotation = Quaternion(-0.00231427, -0.00117056, 0.00930059, 0.999953)
bones/14/rotation = Quaternion(-0.00166558, -0.000807644, 0.00691944, 0.999974)
bones/15/rotation = Quaternion(0.00577591, -0.11751, -0.0487442, 0.991858)
bones/17/rotation = Quaternion(-6.27415e-06, 1.9449e-07, 0.000255723, 1)
bones/19/rotation = Quaternion(-4.38752e-06, 0.00100281, 8.70747e-05, 0.999999)
bones/19/scale = Vector3(1, 1, 1)
bones/23/rotation = Quaternion(-4.20033e-06, 0.000929157, 0.000166562, 1)
bones/24/rotation = Quaternion(-4.96009e-12, 3.17865e-08, 0.000156044, 1)
bones/25/rotation = Quaternion(-2.06265e-06, -3.59192e-08, -0.000221617, 1)
bones/25/scale = Vector3(1, 1, 1)
bones/27/rotation = Quaternion(1.16963e-07, 0.000146031, -0.000799608, 1)
bones/27/scale = Vector3(1, 1, 1)
bones/31/rotation = Quaternion(-5.56963e-06, 0.00156976, -4.12096e-05, 0.999999)
bones/31/scale = Vector3(1, 1, 1)
bones/32/rotation = Quaternion(0.484423, 0.57097, -0.526162, 0.40309)
bones/32/scale = Vector3(1, 1, 1)
bones/33/rotation = Quaternion(-0.0246073, -0.00256146, 0.103505, 0.994321)
bones/36/rotation = Quaternion(0.253096, -0.0613237, 0.227353, 0.938346)
bones/37/rotation = Quaternion(-0.00206509, 0.00104316, -0.00821358, 0.999964)
bones/37/scale = Vector3(1, 1, 1)
bones/39/rotation = Quaternion(0.00515115, 0.122683, 0.0416519, 0.991558)
bones/39/scale = Vector3(1, 1, 1)
bones/43/rotation = Quaternion(-4.301e-06, -0.000377563, -1.30879e-05, 1)
bones/47/rotation = Quaternion(2.8699e-08, -0.00102401, 2.80073e-05, 0.999999)
bones/52/rotation = Quaternion(-4.03591e-06, 7.85054e-08, 0.00204478, 0.999998)
bones/55/scale = Vector3(1, 1, 1)
bones/56/rotation = Quaternion(-4.64504e-08, 0.0103565, 0.999946, 2.51403e-07)
bones/57/rotation = Quaternion(-0.0380914, -8.1369e-08, 9.34877e-09, 0.999274)
bones/58/rotation = Quaternion(0.45974, 3.23798e-08, -1.73487e-07, 0.888054)
bones/58/scale = Vector3(1, 1, 1)
bones/59/rotation = Quaternion(0.335242, 1.52468e-08, -9.76296e-08, 0.942132)
bones/60/rotation = Quaternion(3.66699e-08, 0.0116081, 4.25779e-10, 0.999933)
bones/61/rotation = Quaternion(-8.94691e-08, 0.010368, 0.999946, 2.67749e-07)
bones/61/scale = Vector3(1, 1, 1)
bones/64/rotation = Quaternion(0.335241, 3.90241e-08, -1.40484e-07, 0.942132)
bones/65/rotation = Quaternion(4.9911e-08, -0.0118692, -5.92394e-10, 0.99993)
[node name="AnimationPlayer" parent="XBot2" index="1"]
autoplay = "Idle"
[node name="XBot3" parent="." instance=ExtResource("3_p28sh")]
transform = Transform3D(-0.707107, 0, 0.707107, 0, 1, 0, -0.707107, 0, -0.707107, -5.1, 0, 8)
[node name="Skeleton3D" parent="XBot3/XBot" index="0"]
bones/1/rotation = Quaternion(0.00645836, 1.61788e-09, 2.50506e-07, 0.999979)
bones/1/scale = Vector3(1, 1, 1)
bones/2/rotation = Quaternion(-0.0801557, 2.49493e-14, -2.48068e-07, 0.996782)
bones/4/rotation = Quaternion(0.0128857, -4.77102e-10, -3.70241e-08, 0.999917)
bones/8/rotation = Quaternion(-0.484431, 0.570964, -0.526164, -0.403087)
bones/8/scale = Vector3(1, 1, 1)
bones/9/rotation = Quaternion(-0.024616, 0.00256251, -0.103499, 0.994322)
bones/9/scale = Vector3(1, 1, 1)
bones/12/rotation = Quaternion(0.253284, 0.0616187, -0.22821, 0.938067)
bones/13/rotation = Quaternion(-0.00231427, -0.00117056, 0.00930059, 0.999953)
bones/14/rotation = Quaternion(-0.00166558, -0.000807644, 0.00691944, 0.999974)
bones/15/rotation = Quaternion(0.00577591, -0.11751, -0.0487442, 0.991858)
bones/17/rotation = Quaternion(-6.27415e-06, 1.9449e-07, 0.000255723, 1)
bones/19/rotation = Quaternion(-4.38752e-06, 0.00100281, 8.70747e-05, 0.999999)
bones/19/scale = Vector3(1, 1, 1)
bones/23/rotation = Quaternion(-4.20033e-06, 0.000929157, 0.000166562, 1)
bones/24/rotation = Quaternion(-4.96009e-12, 3.17865e-08, 0.000156044, 1)
bones/25/rotation = Quaternion(-2.06265e-06, -3.59192e-08, -0.000221617, 1)
bones/25/scale = Vector3(1, 1, 1)
bones/27/rotation = Quaternion(1.16963e-07, 0.000146031, -0.000799608, 1)
bones/27/scale = Vector3(1, 1, 1)
bones/31/rotation = Quaternion(-5.56963e-06, 0.00156976, -4.12096e-05, 0.999999)
bones/31/scale = Vector3(1, 1, 1)
bones/32/rotation = Quaternion(0.484423, 0.57097, -0.526162, 0.40309)
bones/32/scale = Vector3(1, 1, 1)
bones/33/rotation = Quaternion(-0.0246073, -0.00256146, 0.103505, 0.994321)
bones/36/rotation = Quaternion(0.253096, -0.0613237, 0.227353, 0.938346)
bones/37/rotation = Quaternion(-0.00206509, 0.00104316, -0.00821358, 0.999964)
bones/37/scale = Vector3(1, 1, 1)
bones/39/rotation = Quaternion(0.00515115, 0.122683, 0.0416519, 0.991558)
bones/39/scale = Vector3(1, 1, 1)
bones/43/rotation = Quaternion(-4.301e-06, -0.000377563, -1.30879e-05, 1)
bones/47/rotation = Quaternion(2.8699e-08, -0.00102401, 2.80073e-05, 0.999999)
bones/52/rotation = Quaternion(-4.03591e-06, 7.85054e-08, 0.00204478, 0.999998)
bones/55/scale = Vector3(1, 1, 1)
bones/56/rotation = Quaternion(-4.64504e-08, 0.0103565, 0.999946, 2.51403e-07)
bones/57/rotation = Quaternion(-0.0380914, -8.1369e-08, 9.34877e-09, 0.999274)
bones/58/rotation = Quaternion(0.45974, 3.23798e-08, -1.73487e-07, 0.888054)
bones/58/scale = Vector3(1, 1, 1)
bones/59/rotation = Quaternion(0.335242, 1.52468e-08, -9.76296e-08, 0.942132)
bones/60/rotation = Quaternion(3.66699e-08, 0.0116081, 4.25779e-10, 0.999933)
bones/61/rotation = Quaternion(-8.94691e-08, 0.010368, 0.999946, 2.67749e-07)
bones/61/scale = Vector3(1, 1, 1)
bones/64/rotation = Quaternion(0.335241, 3.90241e-08, -1.40484e-07, 0.942132)
bones/65/rotation = Quaternion(4.9911e-08, -0.0118692, -5.92394e-10, 0.99993)
[node name="AnimationPlayer" parent="XBot3" index="1"]
autoplay = "Walking Backwards"
[editable path="XBot2"]
[editable path="XBot3"]

View File

@ -0,0 +1,54 @@
shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
uniform float point_size : hint_range(0,128);
uniform float roughness : hint_range(0,1);
uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
uniform float specular;
uniform float metallic;
varying vec3 uv1_triplanar_pos;
uniform float uv1_blend_sharpness;
varying vec3 uv1_power_normal;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
void vertex() {
TANGENT = vec3(0.0,0.0,-1.0) * abs(NORMAL.x);
TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.y);
TANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);
TANGENT = normalize(TANGENT);
BINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);
BINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);
BINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);
BINORMAL = normalize(BINORMAL);
uv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));
uv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;
uv1_power_normal/=dot(uv1_power_normal,vec3(1.0));
uv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);
}
vec4 triplanar_texture(sampler2D p_sampler,vec3 p_weights,vec3 p_triplanar_pos) {
vec4 samp=vec4(0.0);
samp+= texture(p_sampler,p_triplanar_pos.xy) * p_weights.z;
samp+= texture(p_sampler,p_triplanar_pos.xz) * p_weights.y;
samp+= texture(p_sampler,p_triplanar_pos.zy * vec2(-1.0,1.0)) * p_weights.x;
return samp;
}
void fragment() {
vec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);
ALBEDO = (albedo.rgb * albedo_tex.r) + albedo_tex.g + albedo_tex.b;
float metallic_tex = dot(triplanar_texture(texture_metallic,uv1_power_normal,uv1_triplanar_pos),metallic_texture_channel);
METALLIC = metallic_tex * metallic;
vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
float roughness_tex = dot(triplanar_texture(texture_roughness,uv1_power_normal,uv1_triplanar_pos),roughness_texture_channel);
ROUGHNESS = (1.0 - albedo_tex.g) * roughness;
SPECULAR = specular;
}

1
Content/icon.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 994 B

37
Content/icon.svg.import Normal file
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cclpvkd02o3v7"
path="res://.godot/imported/icon.svg-f57a39bca7a70f3bdadc52234333503e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Content/icon.svg"
dest_files=["res://.godot/imported/icon.svg-f57a39bca7a70f3bdadc52234333503e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

40
Entities/Player/Player.cs Normal file
View File

@ -0,0 +1,40 @@
using System.Collections.Generic;
using Godot;
using KarrotStarterTemplate.Common.CameraController;
using KarrotStarterTemplate.Common.CharacterMovement;
namespace KarrotStarterTemplate.Entities.Player;
public partial class Player : CharacterBody3D
{
private CharacterMovementController _movementController;
private CharacterCameraController _cameraController;
private AnimationTree _animationTree;
private PlayerStateMachine _stateMachine;
private Vector2 _blendPosition;
public override void _Ready()
{
_cameraController = GetNode<CharacterCameraController>("CameraController");
_movementController = GetNode<CharacterMovementController>("MovementController");
_animationTree = GetNode<AnimationTree>("AnimationTree");
_stateMachine = GetNode<PlayerStateMachine>("PlayerStateMachine");
}
public override void _PhysicsProcess(double delta)
{
Vector2 inputDir = Input.GetVector("move_left", "move_right", "move_forward", "move_back");
_stateMachine.package.Add("move_direction", inputDir);
_stateMachine.package.Add("run", Input.IsActionPressed("run"));
_stateMachine.package.Add("roll", Input.IsActionJustPressed("roll"));
// Variant v = _animationTree.GetAnimation("run");
// if (Input.IsActionPressed("run"))
// {
// GD.Print("Add run");
// _stateMachine.AddStateInputsAction("run");
// }
}
}

314
Entities/Player/Player.tscn Normal file
View File

@ -0,0 +1,314 @@
[gd_scene load_steps=32 format=3 uid="uid://br57yle5ldjmr"]
[ext_resource type="Script" path="res://Common/CameraController/CharacterCameraController.cs" id="1_8tlkf"]
[ext_resource type="Script" path="res://Entities/Player/Player.cs" id="1_38iga"]
[ext_resource type="Script" path="res://Common/CharacterMovement/CharacterMovementController.cs" id="1_trsp8"]
[ext_resource type="Script" path="res://Common/CharacterMovement/CharacterMovementMode.cs" id="2_bpavf"]
[ext_resource type="CameraAttributesPractical" uid="uid://r5d50o2xokon" path="res://Resources/Misc/CameraAttributes.tres" id="2_cps54"]
[ext_resource type="PackedScene" uid="uid://cb7dybtexd7ct" path="res://Content/Scenes/Characters/XBot.tscn" id="2_mdp28"]
[ext_resource type="Script" path="res://Common/AnimNotifies/AnimNotify.cs" id="2_s6gd6"]
[ext_resource type="Script" path="res://Entities/Player/PlayerStateMachine.cs" id="3_qdcd8"]
[ext_resource type="Script" path="res://Entities/Player/States/IdleState.cs" id="4_0y3wl"]
[ext_resource type="Script" path="res://Entities/Player/States/WalkState.cs" id="5_l6jgd"]
[ext_resource type="Script" path="res://Entities/Player/States/RollState.cs" id="7_ye038"]
[sub_resource type="Resource" id="Resource_h2cpj"]
script = ExtResource("2_bpavf")
Name = ""
speed = 2.0
ignoreUpDirection = true
acceleration = 1.0
deceleration = 1.0
gravityScale = 1.0
rotationRate = 360.0
[sub_resource type="Resource" id="Resource_gjtqv"]
script = ExtResource("2_bpavf")
Name = ""
speed = 4.0
ignoreUpDirection = true
acceleration = 1.0
deceleration = 1.0
gravityScale = 1.0
rotationRate = 360.0
[sub_resource type="Resource" id="Resource_rjvy2"]
script = ExtResource("2_bpavf")
Name = ""
speed = 4.0
ignoreUpDirection = true
acceleration = 1.0
deceleration = 1.0
gravityScale = 1.0
rotationRate = 360.0
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_inwpe"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_dj5mk"]
animation = &"Stand To Roll"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_a85v2"]
animation = &"Idle"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_fngip"]
animation = &"Running"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_fx22w"]
animation = &"Right Strafe"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_xkc2e"]
animation = &"Left Strafe"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_74w08"]
animation = &"Running Backward"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_k2v8r"]
animation = &"Left Strafe Walk"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ngtvm"]
animation = &"Right Strafe Walk"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_gxvjv"]
animation = &"Walking"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_dktww"]
animation = &"Walking Backwards"
[sub_resource type="AnimationNodeBlendSpace2D" id="AnimationNodeBlendSpace2D_4j2fv"]
blend_point_0/node = SubResource("AnimationNodeAnimation_a85v2")
blend_point_0/pos = Vector2(0, 0)
blend_point_1/node = SubResource("AnimationNodeAnimation_fngip")
blend_point_1/pos = Vector2(0, 4)
blend_point_2/node = SubResource("AnimationNodeAnimation_fx22w")
blend_point_2/pos = Vector2(4, 0)
blend_point_3/node = SubResource("AnimationNodeAnimation_xkc2e")
blend_point_3/pos = Vector2(-4, 0)
blend_point_4/node = SubResource("AnimationNodeAnimation_74w08")
blend_point_4/pos = Vector2(0, -4)
blend_point_5/node = SubResource("AnimationNodeAnimation_k2v8r")
blend_point_5/pos = Vector2(-2, 0)
blend_point_6/node = SubResource("AnimationNodeAnimation_ngtvm")
blend_point_6/pos = Vector2(2, 0)
blend_point_7/node = SubResource("AnimationNodeAnimation_gxvjv")
blend_point_7/pos = Vector2(0, 2)
blend_point_8/node = SubResource("AnimationNodeAnimation_dktww")
blend_point_8/pos = Vector2(0, -2)
min_space = Vector2(-4, -4)
max_space = Vector2(4, 4)
snap = Vector2(1, 1)
sync = true
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_er75r"]
animation = &"Stand To Roll"
[sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_durg8"]
[sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_3il3w"]
[sub_resource type="AnimationNodeTransition" id="AnimationNodeTransition_mfg0f"]
sync = true
xfade_time = 0.3
input_0/name = "locomotion"
input_0/auto_advance = false
input_0/break_loop_at_end = false
input_0/reset = true
input_1/name = "roll"
input_1/auto_advance = false
input_1/break_loop_at_end = false
input_1/reset = true
input_2/name = "doubleRoll"
input_2/auto_advance = false
input_2/break_loop_at_end = false
input_2/reset = true
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_jjrq4"]
"nodes/Animation 2/node" = SubResource("AnimationNodeAnimation_dj5mk")
"nodes/Animation 2/position" = Vector2(-508.316, 402.128)
nodes/LocomotionBlendspace/node = SubResource("AnimationNodeBlendSpace2D_4j2fv")
nodes/LocomotionBlendspace/position = Vector2(-600, -140)
"nodes/Roll anim/node" = SubResource("AnimationNodeAnimation_er75r")
"nodes/Roll anim/position" = Vector2(-520, 200)
nodes/TimeScale/node = SubResource("AnimationNodeTimeScale_3il3w")
nodes/TimeScale/position = Vector2(-320, 180)
"nodes/TimeScale 2/node" = SubResource("AnimationNodeTimeScale_durg8")
"nodes/TimeScale 2/position" = Vector2(-300, 380)
nodes/Transition/node = SubResource("AnimationNodeTransition_mfg0f")
nodes/Transition/position = Vector2(-100, -160)
nodes/output/position = Vector2(140, 0)
node_connections = [&"TimeScale", 0, &"Roll anim", &"TimeScale 2", 0, &"Animation 2", &"Transition", 0, &"LocomotionBlendspace", &"Transition", 1, &"TimeScale", &"Transition", 2, &"TimeScale 2", &"output", 0, &"Transition"]
[node name="Player" type="CharacterBody3D"]
script = ExtResource("1_38iga")
[node name="AnimNotify" type="Node" parent="." node_paths=PackedStringArray("animationPlayer", "animationTree")]
script = ExtResource("2_s6gd6")
animationPlayer = NodePath("../XBot2/AnimationPlayer")
animationTree = NodePath("../AnimationTree")
[node name="PlayerStateMachine" type="Node" parent="." node_paths=PackedStringArray("animationTree", "animationNotify", "characterMovement", "cameraController", "owner", "defaultState")]
unique_name_in_owner = true
script = ExtResource("3_qdcd8")
animationTree = NodePath("../AnimationTree")
animationNotify = NodePath("../AnimNotify")
characterMovement = NodePath("../MovementController")
cameraController = NodePath("../CameraController")
owner = NodePath("..")
defaultState = NodePath("IdleState")
activateOnReady = true
[node name="IdleState" type="Node" parent="PlayerStateMachine"]
script = ExtResource("4_0y3wl")
transitionName = "locomotion"
id = "Idle"
[node name="WalkState" type="Node" parent="PlayerStateMachine"]
script = ExtResource("5_l6jgd")
movementMode = SubResource("Resource_h2cpj")
transitionName = "locomotion"
id = "Walk"
[node name="RunState" type="Node" parent="PlayerStateMachine"]
script = ExtResource("5_l6jgd")
movementMode = SubResource("Resource_gjtqv")
transitionName = "locomotion"
id = "Run"
[node name="RollState" type="Node" parent="PlayerStateMachine"]
script = ExtResource("7_ye038")
noInputDirectionTypeFallback = 0
transitionName = "roll"
id = "Roll"
canTransitionToSelf = true
[node name="DoubleRollState" type="Node" parent="PlayerStateMachine"]
script = ExtResource("7_ye038")
transitionName = "doubleRoll"
id = "DoubleRoll"
canTransitionToSelf = true
[node name="MovementController" type="Node" parent="." node_paths=PackedStringArray("animationTree")]
unique_name_in_owner = true
script = ExtResource("1_trsp8")
defaultMovementMode = SubResource("Resource_rjvy2")
animationTree = NodePath("../AnimationTree")
[node name="CameraController" type="Node3D" parent="." node_paths=PackedStringArray("characterToFollow")]
unique_name_in_owner = true
top_level = true
script = ExtResource("1_8tlkf")
characterToFollow = NodePath("..")
enableInput = false
rotatePlayer = false
[node name="SpringArm3D" type="SpringArm3D" parent="CameraController"]
transform = Transform3D(0.707107, -0.5, 0.5, 0, 0.707107, 0.707107, -0.707107, -0.5, 0.5, 0, 0.9, 0)
collision_mask = 0
spring_length = 15.0
[node name="Camera3D" type="Camera3D" parent="CameraController/SpringArm3D"]
attributes = ExtResource("2_cps54")
fov = 25.0
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_inwpe")
[node name="XBot2" parent="." instance=ExtResource("2_mdp28")]
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0)
[node name="Skeleton3D" parent="XBot2/XBot" index="0"]
bones/0/position = Vector3(-0.0094865, 1.25185e-09, 0.0105013)
bones/1/position = Vector3(-6.98528e-08, 1.0277, 0.0153483)
bones/1/rotation = Quaternion(-0.0299539, -0.36772, -0.0121686, 0.929374)
bones/1/scale = Vector3(1, 1, 1)
bones/2/rotation = Quaternion(-0.029804, 0.0412832, -0.00444647, 0.998693)
bones/3/rotation = Quaternion(0.100643, 0.0829519, -0.00643562, 0.991438)
bones/4/rotation = Quaternion(0.11341, 0.082862, -0.00750396, 0.990058)
bones/5/rotation = Quaternion(-0.03756, -0.0112204, 0.000859207, 0.999231)
bones/6/rotation = Quaternion(-0.0544206, 0.177227, 0.00865648, 0.982626)
bones/8/rotation = Quaternion(-0.579974, 0.502586, -0.515842, -0.380717)
bones/8/scale = Vector3(1, 1, 1)
bones/9/rotation = Quaternion(0.477713, 0.052378, 0.0945921, 0.871837)
bones/9/scale = Vector3(1, 1, 1)
bones/10/rotation = Quaternion(0.0446996, 0.029114, -0.359539, 0.931604)
bones/11/rotation = Quaternion(0.106754, -0.0646036, -0.10112, 0.987018)
bones/12/rotation = Quaternion(0.233202, 0.145699, -0.20617, 0.939086)
bones/13/rotation = Quaternion(-0.0431753, 0.000711064, 0.1877, 0.981277)
bones/14/rotation = Quaternion(-0.0016657, -0.000807656, 0.00691934, 0.999974)
bones/15/rotation = Quaternion(0.00577591, -0.11751, -0.0487442, 0.991858)
bones/16/rotation = Quaternion(0.0395755, 0.00997601, 0.0100787, 0.999116)
bones/17/rotation = Quaternion(0.147281, 0.000491134, 0.0101569, 0.989042)
bones/18/rotation = Quaternion(1.05725e-05, -1.8822e-07, -8.80717e-05, 1)
bones/19/rotation = Quaternion(-4.38752e-06, 0.00100281, 8.70747e-05, 0.999999)
bones/19/scale = Vector3(1, 1, 1)
bones/20/rotation = Quaternion(0.11099, 0.00848848, 0.0240655, 0.993494)
bones/21/rotation = Quaternion(0.263547, 0.00145656, -0.0162155, 0.964509)
bones/22/rotation = Quaternion(2.01072e-06, -2.82134e-07, -0.000321912, 1)
bones/23/rotation = Quaternion(-4.20033e-06, 0.000929157, 0.000166562, 1)
bones/24/rotation = Quaternion(0.186998, -0.00841205, 0.0675611, 0.979998)
bones/25/rotation = Quaternion(0.320396, -0.00244664, -0.0342687, 0.946661)
bones/25/scale = Vector3(1, 1, 1)
bones/26/rotation = Quaternion(2.07526e-06, 2.07746e-08, -0.000112557, 1)
bones/27/rotation = Quaternion(1.16963e-07, 0.000146031, -0.000799608, 1)
bones/27/scale = Vector3(1, 1, 1)
bones/28/rotation = Quaternion(0.207746, -0.020696, 0.0882186, 0.973977)
bones/29/rotation = Quaternion(0.349305, -0.0117833, -0.067892, 0.934472)
bones/30/rotation = Quaternion(5.61877e-06, -2.38827e-07, -0.00049686, 1)
bones/31/rotation = Quaternion(-5.56963e-06, 0.00156976, -4.12096e-05, 0.999999)
bones/31/scale = Vector3(1, 1, 1)
bones/32/rotation = Quaternion(0.525951, 0.544071, -0.54701, 0.35797)
bones/32/scale = Vector3(1, 1, 1)
bones/33/rotation = Quaternion(0.510818, -0.0627656, 0.138661, 0.846108)
bones/34/rotation = Quaternion(-0.0125484, 0.0578293, 0.404985, 0.912406)
bones/35/rotation = Quaternion(-0.162766, 0.140065, 0.0151678, 0.976555)
bones/36/rotation = Quaternion(0.307937, -0.0089344, 0.161255, 0.937599)
bones/37/rotation = Quaternion(-0.00937778, 0.00174634, -0.00701192, 0.99993)
bones/37/scale = Vector3(1, 1, 1)
bones/38/rotation = Quaternion(-0.00153038, 0.000745069, -0.0060738, 0.99998)
bones/39/rotation = Quaternion(0.00515115, 0.122683, 0.0416519, 0.991558)
bones/39/scale = Vector3(1, 1, 1)
bones/40/rotation = Quaternion(0.0326842, -0.005891, 0.0610618, 0.997581)
bones/41/rotation = Quaternion(0.142788, -0.000761521, -0.00690043, 0.989729)
bones/42/rotation = Quaternion(2.20277e-06, -7.01971e-08, -6.63367e-05, 1)
bones/43/rotation = Quaternion(-4.301e-06, -0.000377563, -1.30879e-05, 1)
bones/44/rotation = Quaternion(0.124651, 0.00607029, -0.0858307, 0.988463)
bones/45/rotation = Quaternion(0.189666, -0.00166462, 0.0146905, 0.981737)
bones/46/rotation = Quaternion(-4.03633e-06, -2.86042e-07, 2.04936e-05, 1)
bones/47/rotation = Quaternion(2.8699e-08, -0.00102401, 2.80073e-05, 0.999999)
bones/48/rotation = Quaternion(0.264953, -0.013301, -0.130867, 0.955247)
bones/49/rotation = Quaternion(0.27558, 0.00173527, 0.0235541, 0.960988)
bones/50/rotation = Quaternion(-4.04939e-06, -4.14508e-07, -6.19588e-07, 1)
bones/52/rotation = Quaternion(0.290944, -0.0134275, -0.162034, 0.942823)
bones/53/rotation = Quaternion(0.33612, 0.0116337, 0.049425, 0.94045)
bones/54/rotation = Quaternion(8.52048e-06, 4.23118e-07, -6.65489e-05, 1)
bones/55/scale = Vector3(1, 1, 1)
bones/56/rotation = Quaternion(-0.125185, 0.041323, 0.983712, 0.122192)
bones/57/rotation = Quaternion(-0.321478, 0.0760856, -0.0240363, 0.943549)
bones/58/rotation = Quaternion(0.605812, 0.0642597, 0.129458, 0.78237)
bones/58/scale = Vector3(1, 1, 1)
bones/59/rotation = Quaternion(0.349854, 0.00382453, -0.00189273, 0.936795)
bones/60/rotation = Quaternion(3.66699e-08, 0.0116081, 4.25779e-10, 0.999933)
bones/61/rotation = Quaternion(0.07882, 0.224764, 0.965855, -0.101941)
bones/61/scale = Vector3(1, 1, 1)
bones/62/rotation = Quaternion(-0.324811, 0.11812, -0.0338818, 0.937762)
bones/63/rotation = Quaternion(0.500957, -0.0282444, -0.0572155, 0.863117)
bones/64/rotation = Quaternion(0.354274, 0.0164946, -0.0237669, 0.934694)
bones/65/rotation = Quaternion(4.9911e-08, -0.0118692, -5.92394e-10, 0.99993)
[node name="AnimationTree" type="AnimationTree" parent="."]
unique_name_in_owner = true
root_node = NodePath("%AnimationTree/../XBot2")
root_motion_track = NodePath("XBot/Skeleton3D:mixamorig_Root")
tree_root = SubResource("AnimationNodeBlendTree_jjrq4")
anim_player = NodePath("../XBot2/AnimationPlayer")
parameters/LocomotionBlendspace/blend_position = Vector2(0, 0)
parameters/TimeScale/scale = 2.0
"parameters/TimeScale 2/scale" = 2.0
parameters/Transition/current_state = "roll"
parameters/Transition/transition_request = ""
parameters/Transition/current_index = 1
[node name="RootMotionView" type="RootMotionView" parent="."]
animation_path = NodePath("../AnimationTree")
[editable path="XBot2"]

View File

@ -0,0 +1,10 @@
using Godot;
using KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
namespace KarrotStarterTemplate.Entities.Player;
[GlobalClass]
public partial class PlayerStateMachine : BasePlayerStateMachine
{
}

View File

@ -0,0 +1,10 @@
using Godot;
using KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
namespace KarrotStarterTemplate.Entities.Player.States;
[GlobalClass]
public partial class IdleState : MovementBasePlayerState
{
}

View File

@ -0,0 +1,69 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Godot;
using KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
namespace KarrotStarterTemplate.Entities.Player.States;
[GlobalClass]
public partial class RollState : RootMotionBasePlayerState
{
protected async override Task OnEnter()
{
await base.OnEnter();
checkRelevance = false;
}
protected override async Task OnExit()
{
await base.OnExit();
}
protected override void OnAnimationNotify(string name, string actionName)
{
if (name == "roll" && actionName == "finish")
{
checkRelevance = true;
}
}
protected override void OnStateProcess(double delta)
{
base.OnStateProcess(delta);
if (package.GetBool("roll") && timeElapsed > 0.4)
{
statesInQueue.Add(id == "Roll" ? "DoubleRoll" : "Roll");
}
}
protected override void OnStatePhysicsProcess(double delta)
{
if (package.GetString("roll") == "finish")
{
}
base.OnStatePhysicsProcess(delta);
}
protected override string OnCheckRelevance()
{
if (statesInQueue.Count > 0) return statesInQueue.Last();
if (!package.GetVector3("move_direction").IsZeroApprox())
{
if (package.GetBool("run"))
{
return "Run";
}
return "Walk";
}
return "Idle";
}
}

View File

@ -0,0 +1,10 @@
using Godot;
using KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
namespace KarrotStarterTemplate.Entities.Player.States;
[GlobalClass]
public partial class RunState : MovementBasePlayerState
{
}

View File

@ -0,0 +1,10 @@
using Godot;
using KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
namespace KarrotStarterTemplate.Entities.Player.States;
[GlobalClass]
public partial class WalkState : MovementBasePlayerState
{
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Godot.NET.Sdk/4.3.0">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>KarrotStarterTemplate</RootNamespace>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Karrot Starter Template", "Karrot Starter Template.csproj", "{B488EE78-25AF-4D74-9324-860469DB4DE7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
ExportDebug|Any CPU = ExportDebug|Any CPU
ExportRelease|Any CPU = ExportRelease|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B488EE78-25AF-4D74-9324-860469DB4DE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B488EE78-25AF-4D74-9324-860469DB4DE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B488EE78-25AF-4D74-9324-860469DB4DE7}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
{B488EE78-25AF-4D74-9324-860469DB4DE7}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
{B488EE78-25AF-4D74-9324-860469DB4DE7}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
{B488EE78-25AF-4D74-9324-860469DB4DE7}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAction_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F14a2b70486934722acea07b38045413ab2d200_003F52_003Fc3079672_003FAction_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APlane_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F08f0ea1144634eedbe3a87b9762ef1dd4bd200_003F01_003Fb031f156_003FPlane_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/Monitoring/StartMode/@EntryValue">OnDebug</s:String></wpf:ResourceDictionary>

View File

@ -0,0 +1,12 @@
[gd_resource type="CameraAttributesPractical" format=3 uid="uid://r5d50o2xokon"]
[resource]
auto_exposure_enabled = true
auto_exposure_scale = 0.3
dof_blur_far_enabled = true
dof_blur_far_distance = 8.0
dof_blur_far_transition = 20.0
dof_blur_near_enabled = true
dof_blur_near_distance = 15.0
dof_blur_near_transition = 5.0
auto_exposure_min_sensitivity = 20.0

View File

@ -0,0 +1,20 @@
[gd_resource type="Environment" load_steps=3 format=3 uid="uid://c1jlxnbw1vwp1"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_uvoho"]
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_0fhru"]
sky_material = SubResource("ProceduralSkyMaterial_uvoho")
[resource]
background_mode = 2
sky = SubResource("Sky_0fhru")
tonemap_mode = 3
ssr_enabled = true
ssao_enabled = true
ssil_enabled = true
sdfgi_enabled = true
glow_enabled = true
volumetric_fog_enabled = true
volumetric_fog_density = 0.02

View File

@ -0,0 +1,227 @@
extends CompositorEffect
var rd: RenderingDevice
var linear_sampler: RID
var nearest_sampler : RID
var context: StringName = "PostProcess"
var all_shader_stages : Dictionary
@export var debug : bool = false:
set(value):
if(debug == value):
return
debug = value
free_shaders.call_deferred()
generate_shaders.call_deferred()
var debug_1 : String = "debug_1"
var debug_2 : String = "debug_2"
var debug_3 : String = "debug_3"
var debug_4 : String = "debug_4"
var debug_5 : String = "debug_5"
var debug_6 : String = "debug_6"
var debug_7 : String = "debug_7"
var debug_8 : String = "debug_8"
var all_debug_images : Array[RID]
func _init():
RenderingServer.call_on_render_thread(_initialize_compute)
func _notification(what):
if what == NOTIFICATION_PREDELETE:
if !rd:
return
if linear_sampler.is_valid():
rd.free_rid(linear_sampler)
if nearest_sampler.is_valid():
rd.free_rid(nearest_sampler)
for shader_stage in all_shader_stages.keys():
if shader_stage.pipeline.is_valid():
rd.free_rid(shader_stage.pipeline)
if shader_stage.shader.is_valid():
rd.free_rid(shader_stage.shader)
func free_shaders():
for shader_stage in all_shader_stages.keys():
if shader_stage.pipeline.is_valid():
rd.free_rid(shader_stage.pipeline)
if shader_stage.shader.is_valid():
rd.free_rid(shader_stage.shader)
func generate_shaders():
for shader_stage in all_shader_stages.keys():
generate_shader_stage(shader_stage)
func subscirbe_shader_stage(shader_stage : ShaderStageResource):
if all_shader_stages.has(shader_stage):
return
all_shader_stages[shader_stage] = 1
if rd:
generate_shader_stage(shader_stage)
func unsubscribe_shader_stage(shader_stage : ShaderStageResource):
if all_shader_stages.has(shader_stage):
all_shader_stages.erase(shader_stage)
if !rd:
return
if shader_stage.shader.is_valid():
rd.free_rid(shader_stage.shader)
if shader_stage.pipeline.is_valid():
rd.free_rid(shader_stage.pipeline)
func _initialize_compute():
rd = RenderingServer.get_rendering_device()
if !rd:
return
var sampler_state := RDSamplerState.new()
sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_LINEAR
sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
linear_sampler = rd.sampler_create(sampler_state)
sampler_state.min_filter = RenderingDevice.SAMPLER_FILTER_NEAREST
sampler_state.mag_filter = RenderingDevice.SAMPLER_FILTER_NEAREST
sampler_state.repeat_u = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
sampler_state.repeat_v = RenderingDevice.SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE
nearest_sampler = rd.sampler_create(sampler_state)
generate_shaders()
func generate_shader_stage(shader_stage : ShaderStageResource):
var shader_spirv : RDShaderSPIRV
if debug:
var file = FileAccess.open(shader_stage.shader_file.resource_path, FileAccess.READ)
var split_shader : PackedStringArray = file.get_as_text().split("#[compute]", true, 1)
var content : String = split_shader[min(1, split_shader.size() - 1)]
var all_split_parts : PackedStringArray = content.split("#version 450", true, 1)
content = str(all_split_parts[0],
"#version 450
#define DEBUG
layout(rgba16f, set = 0, binding = 10) uniform image2D debug_1_image;
layout(rgba16f, set = 0, binding = 11) uniform image2D debug_2_image;
layout(rgba16f, set = 0, binding = 12) uniform image2D debug_3_image;
layout(rgba16f, set = 0, binding = 13) uniform image2D debug_4_image;
layout(rgba16f, set = 0, binding = 14) uniform image2D debug_5_image;
layout(rgba16f, set = 0, binding = 15) uniform image2D debug_6_image;
layout(rgba16f, set = 0, binding = 16) uniform image2D debug_7_image;
layout(rgba16f, set = 0, binding = 17) uniform image2D debug_8_image;",
all_split_parts[1])
var shader_source : RDShaderSource = RDShaderSource.new()
shader_source.set_stage_source(RenderingDevice.SHADER_STAGE_COMPUTE, content)
shader_spirv = rd.shader_compile_spirv_from_source(shader_source, false)
print(content)
else:
shader_spirv = shader_stage.shader_file.get_spirv()
shader_stage.shader = rd.shader_create_from_spirv(shader_spirv)
shader_stage.pipeline = rd.compute_pipeline_create(shader_stage.shader)
func _render_callback(p_effect_callback_type, p_render_data):
if !rd:
return
var render_scene_buffers: RenderSceneBuffersRD = p_render_data.get_render_scene_buffers()
var render_scene_data: RenderSceneDataRD = p_render_data.get_render_scene_data()
if !render_scene_buffers or !render_scene_data:
return
var render_size: Vector2i = render_scene_buffers.get_internal_size()
if render_size.x == 0 or render_size.y == 0:
return
if debug:
ensure_texture(debug_1, render_scene_buffers)
ensure_texture(debug_2, render_scene_buffers)
ensure_texture(debug_3, render_scene_buffers)
ensure_texture(debug_4, render_scene_buffers)
ensure_texture(debug_5, render_scene_buffers)
ensure_texture(debug_6, render_scene_buffers)
ensure_texture(debug_7, render_scene_buffers)
ensure_texture(debug_8, render_scene_buffers)
var view_count = render_scene_buffers.get_view_count()
for view in range(view_count):
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_1, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_2, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_3, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_4, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_5, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_6, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_7, view, 0, 1, 1))
all_debug_images.append(render_scene_buffers.get_texture_slice(context, debug_8, view, 0, 1, 1))
_render_callback_2(render_size, render_scene_buffers, render_scene_data)
all_debug_images.clear()
func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSceneBuffersRD, render_scene_data : RenderSceneDataRD):
pass
func ensure_texture(texture_name : StringName, render_scene_buffers : RenderSceneBuffersRD, texture_format : RenderingDevice.DataFormat = RenderingDevice.DATA_FORMAT_R16G16B16A16_SFLOAT, render_size_multiplier : Vector2 = Vector2(1, 1)):
var render_size : Vector2i = Vector2(render_scene_buffers.get_internal_size()) * render_size_multiplier
if render_scene_buffers.has_texture(context, texture_name):
var tf: RDTextureFormat = render_scene_buffers.get_texture_format(context, texture_name)
if tf.width != render_size.x or tf.height != render_size.y:
render_scene_buffers.clear_context(context)
if !render_scene_buffers.has_texture(context, texture_name):
var usage_bits: int = RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice.TEXTURE_USAGE_STORAGE_BIT
render_scene_buffers.create_texture(context, texture_name, texture_format, usage_bits, RenderingDevice.TEXTURE_SAMPLES_1, render_size, 1, 1, true)
func get_image_uniform(image: RID, binding: int) -> RDUniform:
var uniform: RDUniform = RDUniform.new()
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_IMAGE
uniform.binding = binding
uniform.add_id(image)
return uniform
func get_sampler_uniform(image: RID, binding: int, linear : bool = true) -> RDUniform:
var uniform: RDUniform = RDUniform.new()
uniform.uniform_type = RenderingDevice.UNIFORM_TYPE_SAMPLER_WITH_TEXTURE
uniform.binding = binding
uniform.add_id(linear_sampler if linear else nearest_sampler)
uniform.add_id(image)
return uniform
func dispatch_stage(stage : ShaderStageResource, uniforms : Array[RDUniform], push_constants : PackedByteArray, dispatch_size : Vector3i, label : String = "DefaultLabel", view : int = 0, color : Color = Color(1, 1, 1, 1)):
rd.draw_command_begin_label(label + " " + str(view), color)
if debug:
for i in 8:
var debug_image_index = i + view * 8;
uniforms.append(get_image_uniform(all_debug_images[debug_image_index], 10 + i))
var tex_uniform_set = UniformSetCacheRD.get_cache(stage.shader, 0, uniforms)
var compute_list = rd.compute_list_begin()
rd.compute_list_bind_compute_pipeline(compute_list, stage.pipeline)
rd.compute_list_bind_uniform_set(compute_list, tex_uniform_set, 0)
if !push_constants.is_empty():
rd.compute_list_set_push_constant(compute_list, push_constants, push_constants.size())
rd.compute_list_dispatch(compute_list, dispatch_size.x, dispatch_size.y, dispatch_size.z)
rd.compute_list_end()
rd.draw_command_end_label()

View File

@ -0,0 +1,49 @@
extends Compositor
class_name MotionBlurCompositor
@export_group("Motion Blur")
# diminishing returns over 16
@export_range(4, 64) var samples: int = 16 :
set(value):
for effect in compositor_effects:
effect.set("samples", value)
samples = value
# you really don't want this over 0.5, but you can if you want to try
@export_range(0, 0.5, 0.001, "or_greater") var intensity: float = 1 :
set(value):
for effect in compositor_effects:
effect.set("intensity", value)
intensity = value
@export_range(0, 1) var center_fade: float = 0.0 :
set(value):
for effect in compositor_effects:
effect.set("center_fade", value)
center_fade = value
## wether this motion blur stays the same intensity below
## target_constant_framerate
@export var framerate_independent : bool = true :
set(value):
for effect in compositor_effects:
effect.set("framerate_independent", value)
framerate_independent = value
## Description: Removes clamping on motion blur scale to allow framerate independent motion
## blur to scale longer than realistically possible when render framerate is higher
## than target framerate.[br][br]
## [color=yellow]Warning:[/color] Turning this on would allow over-blurring of pixels, which
## produces inaccurate results, and would likely cause nausea in players over
## long exposure durations, use with caution and out of artistic intent
@export var uncapped_independence : bool = false :
set(value):
for effect in compositor_effects:
effect.set("uncapped_independence", value)
uncapped_independence = value
## if framerate_independent is enabled, the blur would simulate
## sutter speeds at that framerate, and up.
@export var target_constant_framerate : float = 30 :
set(value):
for effect in compositor_effects:
effect.set("target_constant_framerate", value)
target_constant_framerate = value

View File

@ -0,0 +1,28 @@
extends "res://addons/SphynxMotionBlurToolkit/BaseClasses/enhanced_compositor_effect.gd"
# diminishing returns over 16
var samples: int = 16
# you really don't want this over 0.5, but you can if you want to try
var intensity: float = 1
var center_fade: float = 0.0
## wether this motion blur stays the same intensity below
## target_constant_framerate
var framerate_independent : bool = true
## Description: Removes clamping on motion blur scale to allow framerate independent motion
## blur to scale longer than realistically possible when render framerate is higher
## than target framerate.[br][br]
## [color=yellow]Warning:[/color] Turning this on would allow over-blurring of pixels, which
## produces inaccurate results, and would likely cause nausea in players over
## long exposure durations, use with caution and out of artistic intent
var uncapped_independence : bool = false
## if framerate_independent is enabled, the blur would simulate
## sutter speeds at that framerate, and up.
var target_constant_framerate : float = 30
func _init():
needs_motion_vectors = true
set_deferred("context", "MotionBlur")
super()

View File

@ -0,0 +1,7 @@
extends Resource
class_name ShaderStageResource
@export var shader_file : RDShaderFile
var shader : RID
var pipeline : RID

View File

@ -0,0 +1,87 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
#define DBL_MAX 1.7976931348623158e+308
#define DBL_MIN 2.2250738585072014e-308
layout(rgba16f, set = 0, binding = 0) uniform image2D past_color_image;
layout(rgba16f, set = 0, binding = 1) uniform image2D output_color_image;
layout(set = 0, binding = 2) uniform sampler2D color_sampler;
layout(push_constant, std430) uniform Params
{
float nan_fl_1;
float nan_fl_2;
float nan_fl_3;
float nan_fl_4;
int freeze;
int draw_debug;
int debug_page;
int nan3;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
{
return;
}
// show past image for freeze frame
if(params.freeze > 0)
{
imageStore(output_color_image, uvi, imageLoad(past_color_image, uvi));
return;
}
// must be on pixel center for whole values (tested)
vec2 uvn = vec2(uvi + vec2(0.5)) / render_size;
vec4 source = textureLod(color_sampler, uvn, 0.0);
if (params.draw_debug == 0)
{
imageStore(output_color_image, uvi, source);
imageStore(past_color_image, uvi, source);
return;
}
vec4 tl_col;
vec4 tr_col;
vec4 bl_col;
vec4 br_col;
#ifdef DEBUG
if(params.debug_page == 0)
{
tl_col = imageLoad(debug_1_image, uvi);
tr_col = imageLoad(debug_2_image, uvi);
bl_col = imageLoad(debug_3_image, uvi);
br_col = imageLoad(debug_4_image, uvi);
}
if(params.debug_page == 1)
{
tl_col = imageLoad(debug_5_image, uvi);
tr_col = imageLoad(debug_6_image, uvi);
bl_col = imageLoad(debug_7_image, uvi);
br_col = imageLoad(debug_8_image, uvi);
}
#endif
imageStore(output_color_image, uvi / 2, tl_col);
imageStore(output_color_image, uvi / 2 + ivec2(vec2(0.5, 0.5) * render_size), br_col);
imageStore(output_color_image, uvi / 2 + ivec2(vec2(0.0, 0.5) * render_size), bl_col);
imageStore(output_color_image, uvi / 2 + ivec2(vec2(0.5, 0.0) * render_size), tr_col);
imageStore(past_color_image, uvi / 2, tl_col);
imageStore(past_color_image, uvi / 2 + ivec2(vec2(0.5, 0.5) * render_size), br_col);
imageStore(past_color_image, uvi / 2 + ivec2(vec2(0.0, 0.5) * render_size), bl_col);
imageStore(past_color_image, uvi / 2 + ivec2(vec2(0.5, 0.0) * render_size), tr_col);
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://dyxn6g5gvoge7"
path="res://.godot/imported/debug_overlay.glsl-5ad15477a64c7f484bc494103ad163b6.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Debug/ShaderFiles/debug_overlay.glsl"
dest_files=["res://.godot/imported/debug_overlay.glsl-5ad15477a64c7f484bc494103ad163b6.res"]
[params]

View File

@ -0,0 +1,8 @@
[gd_resource type="Resource" script_class="ShaderStageResource" load_steps=3 format=3 uid="uid://o2bivm33b0v4"]
[ext_resource type="Script" path="res://addons/SphynxMotionBlurToolkit/BaseClasses/shader_pass_resource.gd" id="1_rqnmr"]
[ext_resource type="RDShaderFile" uid="uid://dyxn6g5gvoge7" path="res://addons/SphynxMotionBlurToolkit/Debug/ShaderFiles/debug_overlay.glsl" id="2_qgd1y"]
[resource]
script = ExtResource("1_rqnmr")
shader_file = ExtResource("2_qgd1y")

View File

@ -0,0 +1,99 @@
extends "res://addons/SphynxMotionBlurToolkit/BaseClasses/enhanced_compositor_effect.gd"
class_name DebugCompositorEffect
@export var overlay_stage : ShaderStageResource = preload("res://addons/SphynxMotionBlurToolkit/Debug/debug_overlay_shader_stage.tres"):
set(value):
unsubscribe_shader_stage(overlay_stage)
overlay_stage = value
subscirbe_shader_stage(value)
## wether to display debug views for velocity and depth
## buffers
@export var draw_debug : bool = false
## currently 0 - 1, flip between velocity buffers
## and depth buffers debug views
@export var debug_page : int = 0
var past_color : StringName = "past_color"
var freeze : bool = false
func _init():
set_deferred("context", "MotionBlur")
set_deferred("debug", true)
super()
func _render_callback_2(render_size : Vector2i, render_scene_buffers : RenderSceneBuffersRD, render_scene_data : RenderSceneDataRD):
ensure_texture(past_color, render_scene_buffers)
ensure_texture(debug_1, render_scene_buffers)
ensure_texture(debug_2, render_scene_buffers)
ensure_texture(debug_3, render_scene_buffers)
ensure_texture(debug_4, render_scene_buffers)
ensure_texture(debug_5, render_scene_buffers)
ensure_texture(debug_6, render_scene_buffers)
ensure_texture(debug_7, render_scene_buffers)
ensure_texture(debug_8, render_scene_buffers)
rd.draw_command_begin_label("Debug", Color(1.0, 1.0, 1.0, 1.0))
if Input.is_action_just_pressed("freeze"):
freeze = !freeze
if Input.is_action_just_pressed("Z"):
draw_debug = !draw_debug
if Input.is_action_just_pressed("C"):
debug_page = 1 if debug_page == 0 else 0
var push_constant: PackedFloat32Array = [
0,
0,
0,
0,
]
var int_push_constant : PackedInt32Array = [
freeze,
draw_debug,
debug_page,
0
]
var byte_array = push_constant.to_byte_array()
byte_array.append_array(int_push_constant.to_byte_array())
var view_count = render_scene_buffers.get_view_count()
for view in range(view_count):
var color_image := render_scene_buffers.get_color_layer(view)
var past_color_image := render_scene_buffers.get_texture_slice(context, past_color, view, 0, 1, 1)
var debug_1_image := render_scene_buffers.get_texture_slice(context, debug_1, view, 0, 1, 1)
var debug_2_image := render_scene_buffers.get_texture_slice(context, debug_2, view, 0, 1, 1)
var debug_3_image := render_scene_buffers.get_texture_slice(context, debug_3, view, 0, 1, 1)
var debug_4_image := render_scene_buffers.get_texture_slice(context, debug_4, view, 0, 1, 1)
var debug_5_image := render_scene_buffers.get_texture_slice(context, debug_5, view, 0, 1, 1)
var debug_6_image := render_scene_buffers.get_texture_slice(context, debug_6, view, 0, 1, 1)
var debug_7_image := render_scene_buffers.get_texture_slice(context, debug_7, view, 0, 1, 1)
var debug_8_image := render_scene_buffers.get_texture_slice(context, debug_8, view, 0, 1, 1)
var x_groups := floori((render_size.x - 1) / 16 + 1)
var y_groups := floori((render_size.y - 1) / 16 + 1)
dispatch_stage(overlay_stage,
[
get_image_uniform(past_color_image, 0),
get_image_uniform(color_image, 1),
get_sampler_uniform(color_image, 2),
get_sampler_uniform(debug_1_image, 3),
get_sampler_uniform(debug_2_image, 4),
get_sampler_uniform(debug_3_image, 5),
get_sampler_uniform(debug_4_image, 6),
get_sampler_uniform(debug_5_image, 7),
get_sampler_uniform(debug_6_image, 8),
get_sampler_uniform(debug_7_image, 9),
get_sampler_uniform(debug_8_image, 10),
],
byte_array,
Vector3i(x_groups, y_groups, 1),
"Debug Overlay",
view)
rd.draw_command_end_label()

View File

@ -0,0 +1,156 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
layout(set = 0, binding = 0) uniform sampler2D color_sampler;
layout(set = 0, binding = 1) uniform sampler2D depth_sampler;
layout(set = 0, binding = 2) uniform sampler2D velocity_sampler;
layout(set = 0, binding = 3) uniform sampler2D neighbor_max;
layout(set = 0, binding = 4) uniform sampler2D tile_variance;
layout(rgba16f, set = 0, binding = 5) uniform writeonly image2D output_color;
layout(rgba16f, set = 0, binding = 6) uniform image2D debug_1_image;
layout(rgba16f, set = 0, binding = 7) uniform image2D debug_2_image;
layout(push_constant, std430) uniform Params
{
float minimum_user_threshold;
float importance_bias;
float maximum_jitter_value;
float nan8;
int tile_size;
int sample_count;
int frame;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
// ----------------------------------------------------------
float soft_depth_compare(float depth_X, float depth_Y, float sze)
{
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
}
float cone(float T, float v)
{
return clamp(1 - abs(T) / v, 0, 1);
}
float cylinder(float T, float v)
{
return 1.0 - smoothstep(0.95 * v, 1.05 * v, abs(T));
}
// ----------------------------------------------------------
// Guertin's functions https://research.nvidia.com/sites/default/files/pubs/2013-11_A-Fast-and/Guertin2013MotionBlur-small.pdf
// ----------------------------------------------------------
float z_compare(float a, float b)
{
return clamp(1. - (a - b) / min(a, b), 0, 1);
}
// ----------------------------------------------------------
// from https://www.shadertoy.com/view/ftKfzc
// ----------------------------------------------------------
float interleaved_gradient_noise(vec2 uv, int FrameId){
uv += float(FrameId) * (vec2(47, 17) * 0.695);
vec3 magic = vec3( 0.06711056, 0.00583715, 52.9829189 );
return fract(magic.z * fract(dot(uv, magic.xy)));
}
// ----------------------------------------------------------
vec2 sample_random_offset(vec2 uv, float j)
{
return vec2(0);
}
void main()
{
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
ivec2 tile_render_size = ivec2(textureSize(neighbor_max, 0));
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
{
return;
}
vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
float j = interleaved_gradient_noise(uvi, params.frame) * 2. - 1.;
vec2 vn = textureLod(neighbor_max, x, 0.0).xy * render_size / 2;
float vn_length = max(0.5, length(vn));
vec4 base_color = textureLod(color_sampler, x, 0.0);
if(vn_length <= 0.5)
{
imageStore(output_color, uvi, base_color);
imageStore(debug_1_image, uvi, base_color);
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
return;
}
vec2 wn = normalize(vn);
vec2 vx = textureLod(velocity_sampler, x, 0.0).xy * render_size / 2;
float vx_length = max(0.5, length(vx));
vec2 wp = vec2(-wn.y, wn.x);
if(dot(wp, vx) < 0)
{
wp = -wp;
}
vec2 wc = normalize(mix(wp, normalize(vx), (vx_length - 0.5) / params.minimum_user_threshold));
float zx = -0.05 / textureLod(depth_sampler, x, 0.0).x;
float weight = params.sample_count / (params.importance_bias * vx_length);
vec4 sum = base_color * weight;
for(int i = 0; i < params.sample_count; i++)
{
float t = mix(-1.0, 1.0, (i + j * params.maximum_jitter_value + 1.0) / (params.sample_count + 1.0));
vec2 d = ((i % 2) > 0) ? vx : vn;
float T = t * vn_length;
vec2 y = x + t * d / render_size;
vec2 vy = textureLod(velocity_sampler, y, 0.0).xy * render_size / 2;
float vy_length = max(0.5, length(vy));
float zy = -0.05 / textureLod(depth_sampler, y, 0.0).x;
float f = z_compare(zx, zy);
float b = z_compare(zy, zx);
float wa = dot(wc, d);
float wb = dot(normalize(vy), d);
float ay = f * cone(T, 1. / vy_length) * max(FLT_MIN, abs(wb))
+ b * cone(T, 1. / vx_length) * max(FLT_MIN, abs(wa))
+ cylinder(T, min(vx_length, vy_length)) * 2 * max(FLT_MIN, max(abs(wa), abs(wb)));
weight += abs(ay);
sum += ay * textureLod(color_sampler, y, 0.0);
}
sum /= weight;
imageStore(output_color, uvi, sum);
imageStore(debug_1_image, uvi, sum);
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://cbdyfuhewqag8"
path="res://.godot/imported/guertin_blur.glsl-bc647b2d965e982b702f0e036903e801.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_blur.glsl"
dest_files=["res://.godot/imported/guertin_blur.glsl-bc647b2d965e982b702f0e036903e801.res"]
[params]

View File

@ -0,0 +1,200 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
#define M_PI 3.1415926535897932384626433832795
layout(set = 0, binding = 0) uniform sampler2D color_sampler;
layout(set = 0, binding = 1) uniform sampler2D velocity_sampler;
layout(set = 0, binding = 2) uniform sampler2D neighbor_max;
layout(set = 0, binding = 3) uniform sampler2D tile_variance;
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_color;
layout(push_constant, std430) uniform Params
{
float minimum_user_threshold;
float importance_bias;
float maximum_jitter_value;
float motion_blur_intensity;
int tile_size;
int sample_count;
int frame;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
// ----------------------------------------------------------
float soft_depth_compare(float depth_X, float depth_Y, float sze)
{
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
}
float cone(float T, float v)
{
return clamp(1 - T / v, 0, 1);
}
float cylinder(float T, float v)
{
return 1.0 - smoothstep(0.95 * v, 1.05 * v, T);
}
// ----------------------------------------------------------
// Guertin's functions https://research.nvidia.com/sites/default/files/pubs/2013-11_A-Fast-and/Guertin2013MotionBlur-small.pdf
// ----------------------------------------------------------
float z_compare(float a, float b, float sze)
{
return clamp(1. - sze * (a - b), 0, 1);
}
// ----------------------------------------------------------
// from https://www.shadertoy.com/view/ftKfzc
// ----------------------------------------------------------
float interleaved_gradient_noise(vec2 uv){
uv += float(params.frame) * (vec2(47, 17) * 0.695);
vec3 magic = vec3( 0.06711056, 0.00583715, 52.9829189 );
return fract(magic.z * fract(dot(uv, magic.xy)));
}
// ----------------------------------------------------------
// from https://github.com/bradparks/KinoMotion__unity_motion_blur/tree/master
// ----------------------------------------------------------
vec2 safenorm(vec2 v)
{
float l = max(length(v), 1e-6);
return v / l * int(l >= 0.5);
}
vec2 jitter_tile(vec2 uvi)
{
float rx, ry;
float angle = interleaved_gradient_noise(uvi + vec2(2, 0)) * M_PI * 2;
rx = cos(angle);
ry = sin(angle);
return vec2(rx, ry) / textureSize(neighbor_max, 0) / 4;
}
// ----------------------------------------------------------
void main()
{
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
ivec2 tile_render_size = ivec2(textureSize(neighbor_max, 0));
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
{
return;
}
vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
vec4 vnzw = textureLod(neighbor_max, x + vec2(params.tile_size / 2) / vec2(render_size) + jitter_tile(uvi), 0.0) * vec4(render_size / 2., 1, 1) * params.motion_blur_intensity;
vec2 vn = vnzw.xy;
float vn_length = length(vn);
vec4 base_color = textureLod(color_sampler, x, 0.0);
vec4 vxzw = textureLod(velocity_sampler, x, 0.0) * vec4(render_size / 2., 1, 1) * params.motion_blur_intensity;
if(vn_length < 0.5)
{
imageStore(output_color, uvi, base_color);
#ifdef DEBUG
imageStore(debug_1_image, uvi, base_color);
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
imageStore(debug_3_image, uvi, vec4(vxzw.xy / render_size * 2, 0, 1));
imageStore(debug_4_image, uvi, vec4(0));
#endif
return;
}
vec2 wn = safenorm(vn);
vec2 vx = vxzw.xy;
float vx_length = max(0.5, length(vx));
vec2 wx = safenorm(vx);
float j = interleaved_gradient_noise(uvi) * 2. - 1.;
float zx = vxzw.w;
float weight = 1e-6;
vec4 sum = base_color * weight;
float nai_weight = 1e-6;
vec4 nai_sum = base_color * nai_weight;
for(int i = 0; i < params.sample_count; i++)
{
float t = mix(-1.0, 1.0, (i + j * params.maximum_jitter_value + 1.0) / (params.sample_count + 1.0));
bool use_vn = ((i % 2) == 0);
vec2 d = use_vn ? vn : vx;
float dz = use_vn ? vnzw.z : vxzw.z;
vec2 wd = use_vn ? wn : wx;
float T = abs(t * vn_length);
vec2 y = x + t * d / render_size;
float wa = abs(dot(wx, wd));
vec4 vyzw = textureLod(velocity_sampler, y, 0.0) * vec4(render_size / 2, 1, 1) * params.motion_blur_intensity;
vec2 vy = vyzw.xy - dz * t;
float vy_length = max(0.5, length(vy));
float zy = vyzw.w;
float f = z_compare(-zy, -zx, 20000);
float b = z_compare(-zx, -zy, 20000);
float wb = abs(dot(vy / vy_length, wd));
if(use_vn)
{
float ay = f * step(T, vy_length * wb);
weight += ay;
sum += textureLod(color_sampler, y, 0.0) * ay;
}
float nai_ay = b * step(T, vx_length * wa) * 2;
nai_weight += nai_ay;
nai_sum += textureLod(color_sampler, y, 0.0) * nai_ay;
}
sum /= weight;
weight /= params.sample_count / 2;
nai_sum /= nai_weight;
sum = mix(nai_sum, sum, weight);
imageStore(output_color, uvi, sum);
#ifdef DEBUG
imageStore(debug_1_image, uvi, base_color);
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
imageStore(debug_3_image, uvi, vec4(vx / render_size * 2, 0, 1));
imageStore(debug_4_image, uvi, vxzw);
#endif
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://br71y0l0rxt8h"
path="res://.godot/imported/guertin_experimental_blur.glsl-196a1037ea9a4eb1095033202fe161a7.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_experimental_blur.glsl"
dest_files=["res://.godot/imported/guertin_experimental_blur.glsl-196a1037ea9a4eb1095033202fe161a7.res"]
[params]

View File

@ -0,0 +1,191 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
#define M_PI 3.1415926535897932384626433832795
layout(set = 0, binding = 0) uniform sampler2D color_sampler;
layout(set = 0, binding = 1) uniform sampler2D velocity_sampler;
layout(set = 0, binding = 2) uniform sampler2D neighbor_max;
layout(set = 0, binding = 3) uniform sampler2D tile_variance;
layout(rgba16f, set = 0, binding = 4) uniform writeonly image2D output_color;
layout(push_constant, std430) uniform Params
{
float minimum_user_threshold;
float importance_bias;
float maximum_jitter_value;
float motion_blur_intensity;
int tile_size;
int sample_count;
int frame;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
// McGuire's functions https://docs.google.com/document/d/1IIlAKTj-O01hcXEdGxTErQbCHO9iBmRx6oFUy_Jm0fI/edit
// ----------------------------------------------------------
float soft_depth_compare(float depth_X, float depth_Y, float sze)
{
return clamp(1 - (depth_X - depth_Y) / sze, 0, 1);
}
float cone(float T, float v)
{
return clamp(1 - T / v, 0, 1);
}
float cylinder(float T, float v)
{
return 1.0 - smoothstep(0.95 * v, 1.05 * v, T);
}
// ----------------------------------------------------------
// Guertin's functions https://research.nvidia.com/sites/default/files/pubs/2013-11_A-Fast-and/Guertin2013MotionBlur-small.pdf
// ----------------------------------------------------------
float z_compare(float a, float b, float sze)
{
return clamp(1. - sze * (a - b), 0, 1);
}
// ----------------------------------------------------------
// from https://www.shadertoy.com/view/ftKfzc
// ----------------------------------------------------------
float interleaved_gradient_noise(vec2 uv){
uv += float(params.frame) * (vec2(47, 17) * 0.695);
vec3 magic = vec3( 0.06711056, 0.00583715, 52.9829189 );
return fract(magic.z * fract(dot(uv, magic.xy)));
}
// ----------------------------------------------------------
// from https://github.com/bradparks/KinoMotion__unity_motion_blur/tree/master
// ----------------------------------------------------------
vec2 safenorm(vec2 v)
{
float l = max(length(v), 1e-6);
return v / l * int(l >= 0.5);
}
vec2 jitter_tile(vec2 uvi)
{
float rx, ry;
float angle = interleaved_gradient_noise(uvi + vec2(2, 0)) * M_PI * 2;
rx = cos(angle);
ry = sin(angle);
return vec2(rx, ry) / textureSize(neighbor_max, 0) / 4;
}
// ----------------------------------------------------------
void main()
{
ivec2 render_size = ivec2(textureSize(color_sampler, 0));
ivec2 tile_render_size = ivec2(textureSize(neighbor_max, 0));
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
{
return;
}
vec2 x = (vec2(uvi) + vec2(0.5)) / vec2(render_size);
float j = interleaved_gradient_noise(uvi) * 2. - 1.;
vec4 vnzw = textureLod(neighbor_max, x + vec2(params.tile_size / 2) / vec2(render_size) + jitter_tile(uvi), 0.0) * vec4(render_size / 2., 1, 1) * params.motion_blur_intensity;
vec2 vn = vnzw.xy;
float vn_length = length(vn);
vec4 base_color = textureLod(color_sampler, x, 0.0);
if(vn_length < 0.5)
{
imageStore(output_color, uvi, base_color);
#ifdef DEBUG
imageStore(debug_1_image, uvi, base_color);
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
imageStore(debug_3_image, uvi, vec4(0));
imageStore(debug_4_image, uvi, vec4(0));
#endif
return;
}
vec2 wn = safenorm(vn);
vec4 vxzw = textureLod(velocity_sampler, x, 0.0) * vec4(render_size / 2., 1, 1) * params.motion_blur_intensity;
vec2 vx = vxzw.xy;
float vx_length = max(0.5, length(vx));
vec2 wx = safenorm(vx);
vec2 wp = vec2(-wn.y, wn.x);
if(dot(wp, vx) < 0)
{
wp = -wp;
}
vec2 wc = safenorm(mix(wp, wx, clamp((vx_length - 0.5) / params.minimum_user_threshold, 0, 1)));
float zx = vxzw.w;
float total_weight = params.sample_count / (params.importance_bias * vx_length);
vec4 sum = base_color * total_weight;
for(int i = 0; i < params.sample_count; i++)
{
float t = mix(-1.0, 1.0, (i + j * params.maximum_jitter_value + 1.0) / (params.sample_count + 1.0));
vec2 d = ((i % 2) > 0) ? vx : vn;
float dz = ((i % 2) > 0) ? vxzw.z : vnzw.z;
vec2 wd = safenorm(d);
float T = abs(t * vn_length);
vec2 y = x + t * d / render_size;
float wa = dot(wc, wd);
vec4 vyzw = textureLod(velocity_sampler, y, 0.0) * vec4(render_size / 2, 1, 1) * params.motion_blur_intensity;
vec2 vy = vyzw.xy - dz * t;
float vy_length = max(0.5, length(vy));
float zy = vyzw.w;
float f = z_compare(-zy, -zx, 20000);
float b = z_compare(-zx, -zy, 20000);
float wb = abs(dot(vy / vy_length, wd));
float weight = 0.0;
weight += f * cone(T, vy_length) * wb;
weight += b * cone(T, vx_length) * wa;
weight += cylinder(T, min(vy_length, vx_length)) * 2. * max(wa, wb);
total_weight += weight;
sum += weight * textureLod(color_sampler, y, 0.0);
}
sum /= total_weight;
imageStore(output_color, uvi, sum);
#ifdef DEBUG
imageStore(debug_1_image, uvi, sum);
imageStore(debug_2_image, uvi, vec4(vn / render_size * 2, 0, 1));
imageStore(debug_3_image, uvi, vnzw);
imageStore(debug_4_image, uvi, vxzw);
#endif
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://m6rlgfu6i0b3"
path="res://.godot/imported/guertin_kino_blur.glsl-71e9932045a7522115793d60f179d67e.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_kino_blur.glsl"
dest_files=["res://.godot/imported/guertin_kino_blur.glsl-71e9932045a7522115793d60f179d67e.res"]
[params]

View File

@ -0,0 +1,72 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
layout(set = 0, binding = 0) uniform sampler2D tile_max;
layout(rgba16f, set = 0, binding = 1) uniform writeonly image2D neighbor_max;
layout(push_constant, std430) uniform Params
{
float nan5;
float nan6;
float nan7;
float nan8;
int nan1;
int nan2;
int nan3;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
ivec2 render_size = ivec2(textureSize(tile_max, 0));
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
{
return;
}
vec2 uvn = (vec2(uvi) + vec2(0.5)) / render_size;
vec2 max_neighbor_velocity = vec2(0);
float max_neighbor_velocity_length = 0;
for(int i = -1; i < 2; i++)
{
for(int j = -1; j < 2; j++)
{
vec2 current_offset = vec2(1) / vec2(render_size) * vec2(i, j);
vec2 current_uv = uvn + current_offset;
if(current_uv.x < 0 || current_uv.x > 1 || current_uv.y < 0 || current_uv.y > 1)
{
continue;
}
bool is_diagonal = (abs(i) + abs(j) == 2);
vec2 current_neighbor_velocity = textureLod(tile_max, current_uv, 0.0).xy;
bool facing_center = dot(current_neighbor_velocity, current_offset) > 0;
if(is_diagonal && !facing_center)
{
continue;
}
float current_neighbor_velocity_length = dot(current_neighbor_velocity, current_neighbor_velocity);
if(current_neighbor_velocity_length > max_neighbor_velocity_length)
{
max_neighbor_velocity_length = current_neighbor_velocity_length;
max_neighbor_velocity = current_neighbor_velocity;
}
}
}
imageStore(neighbor_max, uvi, vec4(max_neighbor_velocity, 0, 1));
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://bn88jkvr17x4j"
path="res://.godot/imported/guertin_neighbor_max.glsl-91e836516679e0c51b67df5b480ef0af.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_neighbor_max.glsl"
dest_files=["res://.godot/imported/guertin_neighbor_max.glsl-91e836516679e0c51b67df5b480ef0af.res"]
[params]

View File

@ -0,0 +1,18 @@
#[compute]
#version 450
layout(set = 0, binding = 0) uniform sampler2D blur_sampler;
layout(rgba16f, set = 0, binding = 1) uniform image2D color_image;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
ivec2 render_size = ivec2(textureSize(blur_sampler, 0));
ivec2 output_size = imageSize(color_image);
ivec2 uv = ivec2(gl_GlobalInvocationID.xy);
if ((uv.x >= output_size.x) || (uv.y >= output_size.y))
{
return;
}
imageStore(color_image, uv, textureLod(blur_sampler, (vec2(uv) + 0.5) / output_size, 0.0));
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://i6rnwhmss334"
path="res://.godot/imported/guertin_overlay.glsl-506c18362b63cb0a2477b4a4fbfea046.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_overlay.glsl"
dest_files=["res://.godot/imported/guertin_overlay.glsl-506c18362b63cb0a2477b4a4fbfea046.res"]
[params]

View File

@ -0,0 +1,55 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
layout(set = 0, binding = 0) uniform sampler2D velocity_sampler;
layout(set = 0, binding = 1) uniform sampler2D depth_sampler;
layout(rgba16f, set = 0, binding = 2) uniform writeonly image2D tile_max_x;
layout(push_constant, std430) uniform Params
{
float nan5;
float nan6;
float nan7;
float nan8;
int tile_size;
int nan2;
int nan3;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
ivec2 render_size = ivec2(textureSize(velocity_sampler, 0));
ivec2 output_size = imageSize(tile_max_x);
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
ivec2 global_uvi = uvi * ivec2(params.tile_size, 1);
if ((uvi.x >= output_size.x) || (uvi.y >= output_size.y) || (global_uvi.x >= render_size.x) || (global_uvi.y >= render_size.y))
{
return;
}
vec2 uvn = (vec2(global_uvi) + vec2(0.5)) / render_size;
vec4 max_velocity = vec4(0);
float max_velocity_length = -1;
for(int i = 0; i < params.tile_size; i++)
{
vec2 current_uv = uvn + vec2(float(i) / render_size.x, 0);
vec3 velocity_sample = textureLod(velocity_sampler, current_uv, 0.0).xyz;
float current_velocity_length = dot(velocity_sample.xy, velocity_sample.xy);
if(current_velocity_length > max_velocity_length)
{
max_velocity_length = current_velocity_length;
max_velocity = vec4(velocity_sample, textureLod(depth_sampler, current_uv, 0.0).x);
}
}
imageStore(tile_max_x, uvi, max_velocity);
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://d0s5upcgm7r6l"
path="res://.godot/imported/guertin_tile_max_x.glsl-7ca561425618287b0f2821fd8c232f09.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_tile_max_x.glsl"
dest_files=["res://.godot/imported/guertin_tile_max_x.glsl-7ca561425618287b0f2821fd8c232f09.res"]
[params]

View File

@ -0,0 +1,54 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
layout(set = 0, binding = 0) uniform sampler2D tile_max_x;
layout(rgba16f, set = 0, binding = 1) uniform writeonly image2D tile_max;
layout(push_constant, std430) uniform Params
{
float nan5;
float nan6;
float nan7;
float nan8;
int tile_size;
int nan2;
int nan3;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
ivec2 render_size = ivec2(textureSize(tile_max_x, 0));
ivec2 output_size = imageSize(tile_max);
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
ivec2 global_uvi = uvi * ivec2(1, params.tile_size);
if ((uvi.x >= output_size.x) || (uvi.y >= output_size.y) || (global_uvi.x >= render_size.x) || (global_uvi.y >= render_size.y))
{
return;
}
vec2 uvn = (vec2(global_uvi) + vec2(0.5)) / render_size;
vec4 max_velocity = vec4(0);
float max_velocity_length = -1;
for(int i = 0; i < params.tile_size; i++)
{
vec2 current_uv = uvn + vec2(0, float(i) / render_size.y);
vec4 velocity_sample = textureLod(tile_max_x, current_uv, 0.0);
float current_velocity_length = dot(velocity_sample.xy, velocity_sample.xy);
if(current_velocity_length > max_velocity_length)
{
max_velocity_length = current_velocity_length;
max_velocity = velocity_sample;
}
}
imageStore(tile_max, uvi, max_velocity);
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://ceetvitdbio4l"
path="res://.godot/imported/guertin_tile_max_y.glsl-60f045725ff6917c4bd911cf3710a444.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_tile_max_y.glsl"
dest_files=["res://.godot/imported/guertin_tile_max_y.glsl-60f045725ff6917c4bd911cf3710a444.res"]
[params]

View File

@ -0,0 +1,68 @@
#[compute]
#version 450
#define FLT_MAX 3.402823466e+38
#define FLT_MIN 1.175494351e-38
layout(set = 0, binding = 0) uniform sampler2D tile_max;
layout(rgba16f, set = 0, binding = 1) uniform writeonly image2D tile_variance;
layout(push_constant, std430) uniform Params
{
float nan5;
float nan6;
float nan7;
float nan8;
int nan1;
int nan2;
int nan3;
int nan4;
} params;
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
ivec2 render_size = ivec2(textureSize(tile_max, 0));
ivec2 uvi = ivec2(gl_GlobalInvocationID.xy);
if ((uvi.x >= render_size.x) || (uvi.y >= render_size.y))
{
return;
}
vec2 uvn = (vec2(uvi) + vec2(0.5)) / render_size;
float variance = 0;
vec2 current_velocity = abs(normalize(textureLod(tile_max, uvn, 0.0).xy));
float tile_count = 0;
for(int i = -1; i < 2; i++)
{
for(int j = -1; j < 2; j++)
{
vec2 current_offset = vec2(1) / vec2(render_size) * vec2(i, j);
vec2 current_uv = uvn + current_offset;
if(current_uv.x < 0 || current_uv.x > 1 || current_uv.y < 0 || current_uv.y > 1)
{
continue;
}
if(i == j && i == 0)
{
continue;
}
tile_count += 1;
vec2 current_neighbor_velocity = abs(normalize(textureLod(tile_max, current_uv, 0.0).xy));
variance += dot(current_velocity, current_neighbor_velocity);
}
}
variance /= tile_count;
imageStore(tile_variance, uvi, vec4(1 - variance));
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://by6mslkv0palh"
path="res://.godot/imported/guertin_tile_variance.glsl-2fb44423dc25efae19822b8cfbe32a55.res"
[deps]
source_file="res://addons/SphynxMotionBlurToolkit/Guertin/ShaderFiles/guertin_tile_variance.glsl"
dest_files=["res://.godot/imported/guertin_tile_variance.glsl-2fb44423dc25efae19822b8cfbe32a55.res"]
[params]

Some files were not shown because too many files have changed in this diff Show More