commit dc7e8771e68bae6fe3f146d21d4b288e50b4c143 Author: korboduo Date: Sat Dec 6 15:43:53 2025 +0900 init diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/assets/planar.gdshader b/assets/planar.gdshader new file mode 100644 index 0000000..46bbf0c --- /dev/null +++ b/assets/planar.gdshader @@ -0,0 +1,36 @@ +shader_type spatial; +uniform sampler2D texture_albedo: filter_nearest_mipmap_anisotropic; +uniform vec3 color_albedo:source_color = vec3(1,1,1); +group_uniforms planar; +uniform bool tiling = true; +uniform float tile_scale = 1.0; +uniform float blend_sharpness = 4.0; +varying vec3 world_pos; +varying vec3 world_normal; + +void vertex() { + world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; + world_normal = normalize(mat3(MODEL_MATRIX) * NORMAL); +} + +void fragment() { + vec2 uv = UV; + if (tiling){ + vec3 n = normalize(world_normal); + vec3 abs_normal = abs(n); + float top_weight = pow(abs_normal.y, blend_sharpness); + float side_x_weight = pow(abs_normal.x, blend_sharpness); + float side_z_weight = pow(abs_normal.z, blend_sharpness); + float total_weight = top_weight + side_x_weight + side_z_weight; + top_weight /= total_weight; + side_x_weight /= total_weight; + side_z_weight /= total_weight; + vec2 uv_top = world_pos.xz / -tile_scale; + vec2 uv_side_x = world_pos.zy / -tile_scale; + vec2 uv_side_z = world_pos.xy / -tile_scale; + uv = (top_weight > side_x_weight && top_weight > side_z_weight) ? uv_top : + (side_x_weight > side_z_weight) ? uv_side_x : uv_side_z; + } + ALBEDO = texture(texture_albedo, uv).rgb*color_albedo; +} + diff --git a/assets/planar.gdshader.uid b/assets/planar.gdshader.uid new file mode 100644 index 0000000..c632ae1 --- /dev/null +++ b/assets/planar.gdshader.uid @@ -0,0 +1 @@ +uid://cygvk4t4itjpv diff --git a/assets/prototype/texture_01.png b/assets/prototype/texture_01.png new file mode 100644 index 0000000..9e93d3e Binary files /dev/null and b/assets/prototype/texture_01.png differ diff --git a/assets/prototype/texture_01.png.import b/assets/prototype/texture_01.png.import new file mode 100644 index 0000000..ba755d6 --- /dev/null +++ b/assets/prototype/texture_01.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d32vex3n66fvc" +path="res://.godot/imported/texture_01.png-7a561ae919880fae6fcd6324ffc9d178.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_01.png" +dest_files=["res://.godot/imported/texture_01.png-7a561ae919880fae6fcd6324ffc9d178.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 diff --git a/assets/prototype/texture_01.png:Zone.Identifier b/assets/prototype/texture_01.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_01.png:Zone.Identifier differ diff --git a/assets/prototype/texture_02.png b/assets/prototype/texture_02.png new file mode 100644 index 0000000..c52d0d2 Binary files /dev/null and b/assets/prototype/texture_02.png differ diff --git a/assets/prototype/texture_02.png.import b/assets/prototype/texture_02.png.import new file mode 100644 index 0000000..b3b80c0 --- /dev/null +++ b/assets/prototype/texture_02.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cg6lbwfts577w" +path="res://.godot/imported/texture_02.png-1ea527bfa716785196d479c6b81909de.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_02.png" +dest_files=["res://.godot/imported/texture_02.png-1ea527bfa716785196d479c6b81909de.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 diff --git a/assets/prototype/texture_02.png:Zone.Identifier b/assets/prototype/texture_02.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_02.png:Zone.Identifier differ diff --git a/assets/prototype/texture_03.png b/assets/prototype/texture_03.png new file mode 100644 index 0000000..5960eca Binary files /dev/null and b/assets/prototype/texture_03.png differ diff --git a/assets/prototype/texture_03.png.import b/assets/prototype/texture_03.png.import new file mode 100644 index 0000000..9eb9bbd --- /dev/null +++ b/assets/prototype/texture_03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://byt0c25uubxf3" +path="res://.godot/imported/texture_03.png-75695628e71bab205f2b71558f8188fe.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_03.png" +dest_files=["res://.godot/imported/texture_03.png-75695628e71bab205f2b71558f8188fe.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 diff --git a/assets/prototype/texture_03.png:Zone.Identifier b/assets/prototype/texture_03.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_03.png:Zone.Identifier differ diff --git a/assets/prototype/texture_04.png b/assets/prototype/texture_04.png new file mode 100644 index 0000000..0b9a1d5 Binary files /dev/null and b/assets/prototype/texture_04.png differ diff --git a/assets/prototype/texture_04.png.import b/assets/prototype/texture_04.png.import new file mode 100644 index 0000000..451dd63 --- /dev/null +++ b/assets/prototype/texture_04.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://xq6ha0kitoht" +path="res://.godot/imported/texture_04.png-ca328b3944d1e6cbfd7d4e09efb582b9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_04.png" +dest_files=["res://.godot/imported/texture_04.png-ca328b3944d1e6cbfd7d4e09efb582b9.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 diff --git a/assets/prototype/texture_04.png:Zone.Identifier b/assets/prototype/texture_04.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_04.png:Zone.Identifier differ diff --git a/assets/prototype/texture_05.png b/assets/prototype/texture_05.png new file mode 100644 index 0000000..88f2e5c Binary files /dev/null and b/assets/prototype/texture_05.png differ diff --git a/assets/prototype/texture_05.png.import b/assets/prototype/texture_05.png.import new file mode 100644 index 0000000..02a70f5 --- /dev/null +++ b/assets/prototype/texture_05.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://da07ahmuh45cd" +path="res://.godot/imported/texture_05.png-13097e9615e0bac3f4c3e8026ce28bd1.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_05.png" +dest_files=["res://.godot/imported/texture_05.png-13097e9615e0bac3f4c3e8026ce28bd1.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 diff --git a/assets/prototype/texture_05.png:Zone.Identifier b/assets/prototype/texture_05.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_05.png:Zone.Identifier differ diff --git a/assets/prototype/texture_06.png b/assets/prototype/texture_06.png new file mode 100644 index 0000000..374a5d0 Binary files /dev/null and b/assets/prototype/texture_06.png differ diff --git a/assets/prototype/texture_06.png.import b/assets/prototype/texture_06.png.import new file mode 100644 index 0000000..8d12ba2 --- /dev/null +++ b/assets/prototype/texture_06.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dbbswwmt5holv" +path="res://.godot/imported/texture_06.png-fe0b461ca07979aaa1bc9ddf6c7c870e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_06.png" +dest_files=["res://.godot/imported/texture_06.png-fe0b461ca07979aaa1bc9ddf6c7c870e.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 diff --git a/assets/prototype/texture_06.png:Zone.Identifier b/assets/prototype/texture_06.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_06.png:Zone.Identifier differ diff --git a/assets/prototype/texture_07.png b/assets/prototype/texture_07.png new file mode 100644 index 0000000..34400e3 Binary files /dev/null and b/assets/prototype/texture_07.png differ diff --git a/assets/prototype/texture_07.png.import b/assets/prototype/texture_07.png.import new file mode 100644 index 0000000..9115b85 --- /dev/null +++ b/assets/prototype/texture_07.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://hqqkc51jh2fy" +path="res://.godot/imported/texture_07.png-d893d636bab2e79a76733fbe709a2381.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_07.png" +dest_files=["res://.godot/imported/texture_07.png-d893d636bab2e79a76733fbe709a2381.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 diff --git a/assets/prototype/texture_07.png:Zone.Identifier b/assets/prototype/texture_07.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_07.png:Zone.Identifier differ diff --git a/assets/prototype/texture_08.png b/assets/prototype/texture_08.png new file mode 100644 index 0000000..c5bbc74 Binary files /dev/null and b/assets/prototype/texture_08.png differ diff --git a/assets/prototype/texture_08.png.import b/assets/prototype/texture_08.png.import new file mode 100644 index 0000000..f4e37a3 --- /dev/null +++ b/assets/prototype/texture_08.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://by53qb0l1o51m" +path.s3tc="res://.godot/imported/texture_08.png-e0f6ea5343244945ba2de33bfe0bf210.s3tc.ctex" +metadata={ +"imported_formats": ["s3tc_bptc"], +"vram_texture": true +} + +[deps] + +source_file="res://assets/prototype/texture_08.png" +dest_files=["res://.godot/imported/texture_08.png-e0f6ea5343244945ba2de33bfe0bf210.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 diff --git a/assets/prototype/texture_08.png:Zone.Identifier b/assets/prototype/texture_08.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_08.png:Zone.Identifier differ diff --git a/assets/prototype/texture_09.png b/assets/prototype/texture_09.png new file mode 100644 index 0000000..435e19e Binary files /dev/null and b/assets/prototype/texture_09.png differ diff --git a/assets/prototype/texture_09.png.import b/assets/prototype/texture_09.png.import new file mode 100644 index 0000000..34d9fcf --- /dev/null +++ b/assets/prototype/texture_09.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cqkm2512sx1oc" +path="res://.godot/imported/texture_09.png-415bbd57a7f06a9ceb03e0d59d63e929.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_09.png" +dest_files=["res://.godot/imported/texture_09.png-415bbd57a7f06a9ceb03e0d59d63e929.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 diff --git a/assets/prototype/texture_09.png:Zone.Identifier b/assets/prototype/texture_09.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_09.png:Zone.Identifier differ diff --git a/assets/prototype/texture_10.png b/assets/prototype/texture_10.png new file mode 100644 index 0000000..25ac8ae Binary files /dev/null and b/assets/prototype/texture_10.png differ diff --git a/assets/prototype/texture_10.png.import b/assets/prototype/texture_10.png.import new file mode 100644 index 0000000..30b6dab --- /dev/null +++ b/assets/prototype/texture_10.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://co8oehpme6nba" +path="res://.godot/imported/texture_10.png-ff4960421611582062994f1f35b0c955.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_10.png" +dest_files=["res://.godot/imported/texture_10.png-ff4960421611582062994f1f35b0c955.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 diff --git a/assets/prototype/texture_10.png:Zone.Identifier b/assets/prototype/texture_10.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_10.png:Zone.Identifier differ diff --git a/assets/prototype/texture_11.png b/assets/prototype/texture_11.png new file mode 100644 index 0000000..7d4aebb Binary files /dev/null and b/assets/prototype/texture_11.png differ diff --git a/assets/prototype/texture_11.png.import b/assets/prototype/texture_11.png.import new file mode 100644 index 0000000..6be4377 --- /dev/null +++ b/assets/prototype/texture_11.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bnq5ma4mj2pi4" +path="res://.godot/imported/texture_11.png-67bd04afc561f82765fff77241d77b07.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_11.png" +dest_files=["res://.godot/imported/texture_11.png-67bd04afc561f82765fff77241d77b07.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 diff --git a/assets/prototype/texture_11.png:Zone.Identifier b/assets/prototype/texture_11.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_11.png:Zone.Identifier differ diff --git a/assets/prototype/texture_12.png b/assets/prototype/texture_12.png new file mode 100644 index 0000000..6bd3926 Binary files /dev/null and b/assets/prototype/texture_12.png differ diff --git a/assets/prototype/texture_12.png.import b/assets/prototype/texture_12.png.import new file mode 100644 index 0000000..5d5e73b --- /dev/null +++ b/assets/prototype/texture_12.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cq4vb2bg2msfr" +path="res://.godot/imported/texture_12.png-9e7ce31566681fb48eb15062e9aa4f48.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_12.png" +dest_files=["res://.godot/imported/texture_12.png-9e7ce31566681fb48eb15062e9aa4f48.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 diff --git a/assets/prototype/texture_12.png:Zone.Identifier b/assets/prototype/texture_12.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_12.png:Zone.Identifier differ diff --git a/assets/prototype/texture_13.png b/assets/prototype/texture_13.png new file mode 100644 index 0000000..74515a7 Binary files /dev/null and b/assets/prototype/texture_13.png differ diff --git a/assets/prototype/texture_13.png.import b/assets/prototype/texture_13.png.import new file mode 100644 index 0000000..21a8d92 --- /dev/null +++ b/assets/prototype/texture_13.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bq7iun0a45ppg" +path="res://.godot/imported/texture_13.png-cdb9f5a2f4deed192c320f9eda8da0c7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/prototype/texture_13.png" +dest_files=["res://.godot/imported/texture_13.png-cdb9f5a2f4deed192c320f9eda8da0c7.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 diff --git a/assets/prototype/texture_13.png:Zone.Identifier b/assets/prototype/texture_13.png:Zone.Identifier new file mode 100644 index 0000000..d6c1ec6 Binary files /dev/null and b/assets/prototype/texture_13.png:Zone.Identifier differ diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..9d8b7fa --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..f44362e --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://btjgjjgdnhijb" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/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 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..6fa3779 --- /dev/null +++ b/project.godot @@ -0,0 +1,95 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="first-person" +run/main_scene="uid://dk7oodthk2rt2" +config/features=PackedStringArray("4.4", "Forward Plus") +config/icon="res://icon.svg" + +[autoload] + +GameSettings="*res://scenes/load/game_settings.gd" +Game="*res://scenes/load/game.gd" + +[display] + +window/size/viewport_width=1280 +window/size/viewport_height=720 +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" + +[global_group] + +player="" + +[input] + +up={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +] +} +down={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +] +} +right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +] +} +jump={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null) +] +} +look_up={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) +] +} +look_down={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) +] +} +look_left={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) +] +} +look_right={ +"deadzone": 0.2, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) +] +} + +[layer_names] + +3d_physics/layer_1="environment" +3d_physics/layer_2="physics" +3d_physics/layer_3="player" + +[physics] + +common/physics_interpolation=true diff --git a/scenes/level0.tscn b/scenes/level0.tscn new file mode 100644 index 0000000..0462c02 --- /dev/null +++ b/scenes/level0.tscn @@ -0,0 +1,65 @@ +[gd_scene load_steps=7 format=3 uid="uid://c5nhw4y7f37ll"] + +[ext_resource type="Texture2D" uid="uid://by53qb0l1o51m" path="res://assets/prototype/texture_08.png" id="1_4exd7"] +[ext_resource type="Shader" uid="uid://cygvk4t4itjpv" path="res://assets/planar.gdshader" id="1_ic6my"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_ic6my"] +sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) +ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1) + +[sub_resource type="Sky" id="Sky_qsrgx"] +sky_material = SubResource("ProceduralSkyMaterial_ic6my") + +[sub_resource type="Environment" id="Environment_2h6oo"] +background_mode = 2 +sky = SubResource("Sky_qsrgx") +tonemap_mode = 2 +glow_enabled = true + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_qsrgx"] +render_priority = 0 +shader = ExtResource("1_ic6my") +shader_parameter/texture_albedo = ExtResource("1_4exd7") +shader_parameter/color_albedo = Color(0.303233, 0.303233, 0.303233, 1) +shader_parameter/tiling = true +shader_parameter/tile_scale = 1.0 +shader_parameter/blend_sharpness = 4.0 + +[node name="level0" type="Node3D"] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_2h6oo") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, -0.500003, 0.749999, -0.43301, 0, 0, 0) +shadow_enabled = true + +[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] +material_override = SubResource("ShaderMaterial_qsrgx") +use_collision = true + +[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.5, 0) +size = Vector3(50, 10, 50) + +[node name="CSGBox3D2" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5, 0) +operation = 2 +size = Vector3(49, 10, 49) + +[node name="CSGBox3D3" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 2.5, 10) +size = Vector3(5, 5, 5) + +[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 4.5, 0) +size = Vector3(5, 1, 25) + +[node name="CSGBox3D4" type="CSGPolygon3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 10, 0, 12.5) +polygon = PackedVector2Array(0, 0, 0, 9, 5, 9, 10, 4, 18, 0, 1, 0) +depth = 5.0 + +[node name="CSGBox3D5" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 2.5, -10) +size = Vector3(5, 5, 5) diff --git a/scenes/load/console/console.gd b/scenes/load/console/console.gd new file mode 100644 index 0000000..49b5688 --- /dev/null +++ b/scenes/load/console/console.gd @@ -0,0 +1,144 @@ +extends CanvasLayer + +var player_sensor:Node = null +var active:bool = false +var words:Array = [] +var PrevCMD:String = "" +var light_reading := Color.BLACK +@onready var panel = $control/panel +@onready var menu = $control/panel/menu +@onready var edit = $control/panel/edit +@onready var states = $control/m +@onready var stats = $control/m/stats + +func read_message(message:String): + display_message(message) + words = message.split(" ") + PrevCMD = words[0] + var player = get_tree().get_first_node_in_group("player") + match words[0].to_lower(): + "overdraw": + if words.size() > 1 and is_int(1): + player.camera.get_viewport().debug_draw = words[1].to_int() + "max_fps": + if words.size() > 1 and is_float(1): + Engine.max_fps = words[1].to_float() + "vs": + if DisplayServer.window_get_vsync_mode(0) == DisplayServer.VSYNC_DISABLED: + DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED) + display_event("VSYNC ON") + else: + DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED) + display_event("VSYNC OFF") + "time": + if words.size() > 1: + if is_float(1): + var number = words[1].to_float() + if number >= 0.0 and number < 2.0: + Engine.time_scale = number + else: display_warning("WRONG NUMBER") + else: + display_warning("WRONG NUMBER") + else: + Engine.time_scale = 1 + display_event("TIMESCALE RESTARTED") + "fsr": + if get_viewport().scaling_3d_mode == Viewport.SCALING_3D_MODE_FSR2: + display_event("FSR 2.0 OFF") + get_viewport().scaling_3d_mode = Viewport.SCALING_3D_MODE_BILINEAR + else: + display_event("FSR 2.0 ON") + get_viewport().scaling_3d_mode = Viewport.SCALING_3D_MODE_FSR2 + "render_scale": + if words.size() > 1: + if is_float(1): + get_viewport().scaling_3d_scale = words[1].to_float() + else: + display_warning("WRONG NUMBER") + else: + get_viewport().scaling_3d_scale = 1 + display_event("SCALING RESTARTED") + "fs": + if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) + else: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) + "q": + get_tree().quit() + panel.hide() + +#region Other + +func _input(event): + if event is InputEventKey and event.pressed: + match event.physical_keycode: + KEY_QUOTELEFT: + if panel.visible: panel.hide() + else: panel.show() + KEY_F11: + if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) + else: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) + KEY_F3: + if states.visible: states.hide() + else: states.show() + KEY_F4: + $control/monitor.cycle_debug_menu() + KEY_RIGHT: + if PrevCMD and panel.visible: + edit.set_text(PrevCMD) + edit.set_caret_column(PrevCMD.length()) + +func _process(_delta): + var player = get_tree().get_first_node_in_group("player") + if states.visible and player: + stats.text ="SPEDOMETER: "+str(snappedf(player.spedometer, 0.01)) + +func _ready() -> void: + read_message("vs") + read_message("max_fps 144") + +func _on_edit_text_submitted(new_text): + read_message(new_text) + edit.clear() +func display_event(message:String): + menu.push_color(Color.AQUAMARINE) + menu.add_text(message+"\n") +func display_message(message:String): + menu.push_color(Color.WHITE) + menu.add_text(message+"\n") +func display_warning(message:String): + menu.push_color(Color.YELLOW) + menu.add_text(message+"\n") + +func is_bool(num:int)->bool: + var valid = false + if words.size() > num and words[num].is_valid_int() and \ + words[num].to_int() <= 1 and words[num].to_int() >= 0: + valid = true + return valid + display_warning("WRONG NUMBER") + return valid +func is_float(num:int)->bool: + var valid = false + if words.size() > num and words[num].is_valid_float(): + valid = true + return valid + return valid +func is_int(num:int)->bool: + var valid = false + if words.size() > num and words[num].is_valid_int(): + valid = true + return valid + return valid +func _on_panel_draw(): + active = true + edit.grab_focus() + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) +func _on_panel_hidden(): + active = false + edit.release_focus() + edit.clear() + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) +#endregion diff --git a/scenes/load/console/console.gd.uid b/scenes/load/console/console.gd.uid new file mode 100644 index 0000000..467e423 --- /dev/null +++ b/scenes/load/console/console.gd.uid @@ -0,0 +1 @@ +uid://dy8h0w873m1ck diff --git a/scenes/load/console/console.tscn b/scenes/load/console/console.tscn new file mode 100644 index 0000000..ead981a --- /dev/null +++ b/scenes/load/console/console.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=6 format=3 uid="uid://dp0qvvwtqxt5r"] + +[ext_resource type="Script" uid="uid://dy8h0w873m1ck" path="res://scenes/load/console/console.gd" id="1_1e7mo"] +[ext_resource type="PackedScene" uid="uid://cggqb75a8w8r" path="res://scenes/load/console/debug_menu/debug_menu.tscn" id="2_mnr6t"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_2p7dp"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_60mpv"] +bg_color = Color(0, 0, 0, 0.5) +border_width_top = 1 +border_width_bottom = 1 +border_color = Color(1, 1, 1, 0.101961) + +[sub_resource type="Theme" id="Theme_qg4fp"] +LineEdit/styles/focus = SubResource("StyleBoxEmpty_2p7dp") +LineEdit/styles/normal = SubResource("StyleBoxFlat_60mpv") +LineEdit/styles/read_only = SubResource("StyleBoxFlat_60mpv") +RichTextLabel/styles/focus = SubResource("StyleBoxFlat_60mpv") +RichTextLabel/styles/normal = SubResource("StyleBoxFlat_60mpv") + +[node name="console" type="CanvasLayer"] +layer = 2 +script = ExtResource("1_1e7mo") + +[node name="control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 0 +size_flags_vertical = 0 +mouse_filter = 2 +theme = SubResource("Theme_qg4fp") + +[node name="monitor" parent="control" instance=ExtResource("2_mnr6t")] +visible = false +layout_mode = 1 + +[node name="m" type="MarginContainer" parent="control"] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_constants/margin_left = 25 +theme_override_constants/margin_top = 25 +theme_override_constants/margin_right = 25 +theme_override_constants/margin_bottom = 25 + +[node name="stats" type="Label" parent="control/m"] +layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 0 + +[node name="panel" type="VBoxContainer" parent="control"] +visible = false +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 127.0 +grow_horizontal = 2 +mouse_filter = 2 + +[node name="menu" type="RichTextLabel" parent="control/panel"] +layout_mode = 2 +size_flags_vertical = 3 +scroll_active = false +scroll_following = true + +[node name="edit" type="LineEdit" parent="control/panel"] +layout_mode = 2 + +[connection signal="draw" from="control/panel" to="." method="_on_panel_draw"] +[connection signal="hidden" from="control/panel" to="." method="_on_panel_hidden"] +[connection signal="text_submitted" from="control/panel/edit" to="." method="_on_edit_text_submitted"] diff --git a/scenes/load/console/debug_menu/debug_menu.gd b/scenes/load/console/debug_menu/debug_menu.gd new file mode 100644 index 0000000..4f3fefd --- /dev/null +++ b/scenes/load/console/debug_menu/debug_menu.gd @@ -0,0 +1,469 @@ +extends Control + +@export var fps: Label +@export var frame_time: Label +@export var frame_number: Label +@export var frame_history_total_avg: Label +@export var frame_history_total_min: Label +@export var frame_history_total_max: Label +@export var frame_history_total_last: Label +@export var frame_history_cpu_avg: Label +@export var frame_history_cpu_min: Label +@export var frame_history_cpu_max: Label +@export var frame_history_cpu_last: Label +@export var frame_history_gpu_avg: Label +@export var frame_history_gpu_min: Label +@export var frame_history_gpu_max: Label +@export var frame_history_gpu_last: Label +@export var fps_graph: Panel +@export var total_graph: Panel +@export var cpu_graph: Panel +@export var gpu_graph: Panel +@export var information: Label +@export var settings: Label + +## The number of frames to keep in history for graph drawing and best/worst calculations. +## Currently, this also affects how FPS is measured. +const HISTORY_NUM_FRAMES = 150 + +const GRAPH_SIZE = Vector2(150, 25) +const GRAPH_MIN_FPS = 10 +const GRAPH_MAX_FPS = 160 +const GRAPH_MIN_FRAMETIME = 1.0 / GRAPH_MIN_FPS +const GRAPH_MAX_FRAMETIME = 1.0 / GRAPH_MAX_FPS + +## Debug menu display style. +enum Style { + HIDDEN, ## Debug menu is hidden. + VISIBLE_COMPACT, ## Debug menu is visible, with only the FPS, FPS cap (if any) and time taken to render the last frame. + VISIBLE_DETAILED, ## Debug menu is visible with full information, including graphs. + MAX, ## Represents the size of the Style enum. +} + +## The style to use when drawing the debug menu. +var style := Style.HIDDEN: + set(value): + style = value + match style: + Style.HIDDEN: + visible = false + Style.VISIBLE_COMPACT, Style.VISIBLE_DETAILED: + visible = true + frame_number.visible = style == Style.VISIBLE_DETAILED + $VBoxContainer/FrameTimeHistory.visible = style == Style.VISIBLE_DETAILED + $VBoxContainer/FPSGraph.visible = style == Style.VISIBLE_DETAILED + $VBoxContainer/TotalGraph.visible = style == Style.VISIBLE_DETAILED + $VBoxContainer/CPUGraph.visible = style == Style.VISIBLE_DETAILED + $VBoxContainer/GPUGraph.visible = style == Style.VISIBLE_DETAILED + information.visible = style == Style.VISIBLE_DETAILED + settings.visible = style == Style.VISIBLE_DETAILED + +# Value of `Time.get_ticks_usec()` on the previous frame. +var last_tick := 0 + +var thread := Thread.new() + +## Returns the sum of all values of an array (use as a parameter to `Array.reduce()`). +var sum_func := func avg(accum: float, number: float) -> float: return accum + number + +# History of the last `HISTORY_NUM_FRAMES` rendered frames. +var frame_history_total: Array[float] = [] +var frame_history_cpu: Array[float] = [] +var frame_history_gpu: Array[float] = [] +var fps_history: Array[float] = [] # Only used for graphs. + +var frametime_avg := GRAPH_MIN_FRAMETIME +var frametime_cpu_avg := GRAPH_MAX_FRAMETIME +var frametime_gpu_avg := GRAPH_MIN_FRAMETIME +var frames_per_second := float(GRAPH_MIN_FPS) +var frame_time_gradient := Gradient.new() + +func _init() -> void: + # This must be done here instead of `_ready()` to avoid having `visibility_changed` be emitted immediately. + visible = false + +func _ready() -> void: + fps_graph.draw.connect(_fps_graph_draw) + total_graph.draw.connect(_total_graph_draw) + cpu_graph.draw.connect(_cpu_graph_draw) + gpu_graph.draw.connect(_gpu_graph_draw) + + fps_history.resize(HISTORY_NUM_FRAMES) + frame_history_total.resize(HISTORY_NUM_FRAMES) + frame_history_cpu.resize(HISTORY_NUM_FRAMES) + frame_history_gpu.resize(HISTORY_NUM_FRAMES) + + # NOTE: Both FPS and frametimes are colored following FPS logic + # (red = 10 FPS, yellow = 60 FPS, green = 110 FPS, cyan = 160 FPS). + # This makes the color gradient non-linear. + # Colors are taken from . + frame_time_gradient.set_color(0, Color8(239, 68, 68)) # red-500 + frame_time_gradient.set_color(1, Color8(56, 189, 248)) # light-blue-400 + frame_time_gradient.add_point(0.3333, Color8(250, 204, 21)) # yellow-400 + frame_time_gradient.add_point(0.6667, Color8(128, 226, 95)) # 50-50 mix of lime-400 and green-400 + + get_viewport().size_changed.connect(update_settings_label) + + # Display loading text while information is being queried, + # in case the user toggles the full debug menu just after starting the project. + information.text = "Loading hardware information...\n\n " + settings.text = "Loading project information..." + thread.start( + func(): + # Disable thread safety checks as they interfere with this add-on. + # This only affects this particular thread, not other thread instances in the project. + # See for details. + # Use a Callable so that this can be ignored on Godot 4.0 without causing a script error + # (thread safety checks were added in Godot 4.1). + if Engine.get_version_info()["hex"] >= 0x040100: + Callable(Thread, "set_thread_safety_checks_enabled").call(false) + + # Enable required time measurements to display CPU/GPU frame time information. + # These lines are time-consuming operations, so run them in a separate thread. + RenderingServer.viewport_set_measure_render_time(get_viewport().get_viewport_rid(), true) + update_information_label() + update_settings_label() + ) + + +func cycle_debug_menu() -> void: + style = wrapi(style + 1, 0, Style.MAX) as Style + + +func _exit_tree() -> void: + thread.wait_to_finish() + + +## Update hardware information label (this can change at runtime based on window +## size and graphics settings). This is only called when the window is resized. +## To update when graphics settings are changed, the function must be called manually +## using `DebugMenu.update_settings_label()`. +func update_settings_label() -> void: + settings.text = "" + if ProjectSettings.has_setting("application/config/version"): + settings.text += "Project Version: %s\n" % ProjectSettings.get_setting("application/config/version") + + var rendering_method := str(ProjectSettings.get_setting_with_override("rendering/renderer/rendering_method")) + var rendering_method_string := rendering_method + match rendering_method: + "forward_plus": + rendering_method_string = "Forward+" + "mobile": + rendering_method_string = "Forward Mobile" + "gl_compatibility": + rendering_method_string = "Compatibility" + settings.text += "Rendering Method: %s\n" % rendering_method_string + + var viewport := get_viewport() + + # The size of the viewport rendering, which determines which resolution 3D is rendered at. + var viewport_render_size := Vector2i() + + if viewport.content_scale_mode == Window.CONTENT_SCALE_MODE_VIEWPORT: + viewport_render_size = viewport.get_visible_rect().size + settings.text += "Viewport: %d×%d, Window: %d×%d\n" % [viewport.get_visible_rect().size.x, viewport.get_visible_rect().size.y, viewport.size.x, viewport.size.y] + else: + # Window size matches viewport size. + viewport_render_size = viewport.size + settings.text += "Viewport: %d×%d\n" % [viewport.size.x, viewport.size.y] + + # Display 3D settings only if relevant. + if viewport.get_camera_3d(): + var scaling_3d_mode_string := "(unknown)" + match viewport.scaling_3d_mode: + Viewport.SCALING_3D_MODE_BILINEAR: + scaling_3d_mode_string = "Bilinear" + Viewport.SCALING_3D_MODE_FSR: + scaling_3d_mode_string = "FSR 1.0" + Viewport.SCALING_3D_MODE_FSR2: + scaling_3d_mode_string = "FSR 2.2" + + var antialiasing_3d_string := "" + if viewport.scaling_3d_mode == Viewport.SCALING_3D_MODE_FSR2: + # The FSR2 scaling mode includes its own temporal antialiasing implementation. + antialiasing_3d_string += (" + " if not antialiasing_3d_string.is_empty() else "") + "FSR 2.2" + if viewport.scaling_3d_mode != Viewport.SCALING_3D_MODE_FSR2 and viewport.use_taa: + # Godot's own TAA is ignored when using FSR2 scaling mode, as FSR2 provides its own TAA implementation. + antialiasing_3d_string += (" + " if not antialiasing_3d_string.is_empty() else "") + "TAA" + if viewport.msaa_3d >= Viewport.MSAA_2X: + antialiasing_3d_string += (" + " if not antialiasing_3d_string.is_empty() else "") + "%d× MSAA" % pow(2, viewport.msaa_3d) + if viewport.screen_space_aa == Viewport.SCREEN_SPACE_AA_FXAA: + antialiasing_3d_string += (" + " if not antialiasing_3d_string.is_empty() else "") + "FXAA" + + settings.text += "3D scale (%s): %d%% = %d×%d" % [ + scaling_3d_mode_string, + viewport.scaling_3d_scale * 100, + viewport_render_size.x * viewport.scaling_3d_scale, + viewport_render_size.y * viewport.scaling_3d_scale, + ] + + if not antialiasing_3d_string.is_empty(): + settings.text += "\n3D Antialiasing: %s" % antialiasing_3d_string + + var environment := viewport.get_camera_3d().get_world_3d().environment + if environment: + if environment.ssr_enabled: + settings.text += "\nSSR: %d Steps" % environment.ssr_max_steps + + if environment.ssao_enabled: + settings.text += "\nSSAO: On" + if environment.ssil_enabled: + settings.text += "\nSSIL: On" + + if environment.sdfgi_enabled: + settings.text += "\nSDFGI: %d Cascades" % environment.sdfgi_cascades + + if environment.glow_enabled: + settings.text += "\nGlow: On" + + if environment.volumetric_fog_enabled: + settings.text += "\nVolumetric Fog: On" + var antialiasing_2d_string := "" + if viewport.msaa_2d >= Viewport.MSAA_2X: + antialiasing_2d_string = "%d× MSAA" % pow(2, viewport.msaa_2d) + + if not antialiasing_2d_string.is_empty(): + settings.text += "\n2D Antialiasing: %s" % antialiasing_2d_string + + +## Update hardware/software information label (this never changes at runtime). +func update_information_label() -> void: + var adapter_string := "" + # Make "NVIDIA Corporation" and "NVIDIA" be considered identical (required when using OpenGL to avoid redundancy). + if RenderingServer.get_video_adapter_vendor().trim_suffix(" Corporation") in RenderingServer.get_video_adapter_name(): + # Avoid repeating vendor name before adapter name. + # Trim redundant suffix sometimes reported by NVIDIA graphics cards when using OpenGL. + adapter_string = RenderingServer.get_video_adapter_name().trim_suffix("/PCIe/SSE2") + else: + adapter_string = RenderingServer.get_video_adapter_vendor() + " - " + RenderingServer.get_video_adapter_name().trim_suffix("/PCIe/SSE2") + + # Graphics driver version information isn't always availble. + var driver_info := OS.get_video_adapter_driver_info() + var driver_info_string := "" + if driver_info.size() >= 2: + driver_info_string = driver_info[1] + else: + driver_info_string = "(unknown)" + + var release_string := "" + if OS.has_feature("editor"): + # Editor build (implies `debug`). + release_string = "editor" + elif OS.has_feature("debug"): + # Debug export template build. + release_string = "debug" + else: + # Release export template build. + release_string = "release" + + var rendering_method := str(ProjectSettings.get_setting_with_override("rendering/renderer/rendering_method")) + var rendering_driver := str(ProjectSettings.get_setting_with_override("rendering/rendering_device/driver")) + var graphics_api_string := rendering_driver + if rendering_method != "gl_compatibility": + if rendering_driver == "d3d12": + graphics_api_string = "Direct3D 12" + elif rendering_driver == "metal": + graphics_api_string = "Metal" + elif rendering_driver == "vulkan": + if OS.has_feature("macos") or OS.has_feature("ios"): + graphics_api_string = "Vulkan via MoltenVK" + else: + graphics_api_string = "Vulkan" + else: + if rendering_driver == "opengl3_angle": + graphics_api_string = "OpenGL via ANGLE" + elif OS.has_feature("mobile") or rendering_driver == "opengl3_es": + graphics_api_string = "OpenGL ES" + elif OS.has_feature("web"): + graphics_api_string = "WebGL" + elif rendering_driver == "opengl3": + graphics_api_string = "OpenGL" + + information.text = ( + "%s, %d threads\n" % [OS.get_processor_name().replace("(R)", "").replace("(TM)", ""), OS.get_processor_count()] + + "%s %s (%s %s), %s %s\n" % [OS.get_name(), "64-bit" if OS.has_feature("64") else "32-bit", release_string, "double" if OS.has_feature("double") else "single", graphics_api_string, RenderingServer.get_video_adapter_api_version()] + + "%s, %s" % [adapter_string, driver_info_string] + ) + + +func _fps_graph_draw() -> void: + var fps_polyline := PackedVector2Array() + fps_polyline.resize(HISTORY_NUM_FRAMES) + for fps_index in fps_history.size(): + fps_polyline[fps_index] = Vector2( + remap(fps_index, 0, fps_history.size(), 0, GRAPH_SIZE.x), + remap(clampf(fps_history[fps_index], GRAPH_MIN_FPS, GRAPH_MAX_FPS), GRAPH_MIN_FPS, GRAPH_MAX_FPS, GRAPH_SIZE.y, 0.0) + ) + # Don't use antialiasing to speed up line drawing, but use a width that scales with + # viewport scale to keep the line easily readable on hiDPI displays. + fps_graph.draw_polyline(fps_polyline, frame_time_gradient.sample(remap(frames_per_second, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)), 1.0) + + +func _total_graph_draw() -> void: + var total_polyline := PackedVector2Array() + total_polyline.resize(HISTORY_NUM_FRAMES) + for total_index in frame_history_total.size(): + total_polyline[total_index] = Vector2( + remap(total_index, 0, frame_history_total.size(), 0, GRAPH_SIZE.x), + remap(clampf(frame_history_total[total_index], GRAPH_MIN_FPS, GRAPH_MAX_FPS), GRAPH_MIN_FPS, GRAPH_MAX_FPS, GRAPH_SIZE.y, 0.0) + ) + # Don't use antialiasing to speed up line drawing, but use a width that scales with + # viewport scale to keep the line easily readable on hiDPI displays. + total_graph.draw_polyline(total_polyline, frame_time_gradient.sample(remap(1000.0 / frametime_avg, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)), 1.0) + + +func _cpu_graph_draw() -> void: + var cpu_polyline := PackedVector2Array() + cpu_polyline.resize(HISTORY_NUM_FRAMES) + for cpu_index in frame_history_cpu.size(): + cpu_polyline[cpu_index] = Vector2( + remap(cpu_index, 0, frame_history_cpu.size(), 0, GRAPH_SIZE.x), + remap(clampf(frame_history_cpu[cpu_index], GRAPH_MIN_FPS, GRAPH_MAX_FPS), GRAPH_MIN_FPS, GRAPH_MAX_FPS, GRAPH_SIZE.y, 0.0) + ) + # Don't use antialiasing to speed up line drawing, but use a width that scales with + # viewport scale to keep the line easily readable on hiDPI displays. + cpu_graph.draw_polyline(cpu_polyline, frame_time_gradient.sample(remap(1000.0 / frametime_cpu_avg, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)), 1.0) + + +func _gpu_graph_draw() -> void: + var gpu_polyline := PackedVector2Array() + gpu_polyline.resize(HISTORY_NUM_FRAMES) + for gpu_index in frame_history_gpu.size(): + gpu_polyline[gpu_index] = Vector2( + remap(gpu_index, 0, frame_history_gpu.size(), 0, GRAPH_SIZE.x), + remap(clampf(frame_history_gpu[gpu_index], GRAPH_MIN_FPS, GRAPH_MAX_FPS), GRAPH_MIN_FPS, GRAPH_MAX_FPS, GRAPH_SIZE.y, 0.0) + ) + # Don't use antialiasing to speed up line drawing, but use a width that scales with + # viewport scale to keep the line easily readable on hiDPI displays. + gpu_graph.draw_polyline(gpu_polyline, frame_time_gradient.sample(remap(1000.0 / frametime_gpu_avg, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)), 1.0) + + +func _process(_delta: float) -> void: + if visible: + fps_graph.queue_redraw() + total_graph.queue_redraw() + cpu_graph.queue_redraw() + gpu_graph.queue_redraw() + + # Difference between the last two rendered frames in milliseconds. + var frametime := (Time.get_ticks_usec() - last_tick) * 0.001 + + frame_history_total.push_back(frametime) + if frame_history_total.size() > HISTORY_NUM_FRAMES: + frame_history_total.pop_front() + + # Frametimes are colored following FPS logic (red = 10 FPS, yellow = 60 FPS, green = 110 FPS, cyan = 160 FPS). + # This makes the color gradient non-linear. + frametime_avg = frame_history_total.reduce(sum_func) / frame_history_total.size() + frame_history_total_avg.text = str(frametime_avg).pad_decimals(2) + frame_history_total_avg.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_avg, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_min: float = frame_history_total.min() + frame_history_total_min.text = str(frametime_min).pad_decimals(2) + frame_history_total_min.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_min, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_max: float = frame_history_total.max() + frame_history_total_max.text = str(frametime_max).pad_decimals(2) + frame_history_total_max.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_max, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + frame_history_total_last.text = str(frametime).pad_decimals(2) + frame_history_total_last.modulate = frame_time_gradient.sample(remap(1000.0 / frametime, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var viewport_rid := get_viewport().get_viewport_rid() + var frametime_cpu := RenderingServer.viewport_get_measured_render_time_cpu(viewport_rid) + RenderingServer.get_frame_setup_time_cpu() + frame_history_cpu.push_back(frametime_cpu) + if frame_history_cpu.size() > HISTORY_NUM_FRAMES: + frame_history_cpu.pop_front() + + frametime_cpu_avg = frame_history_cpu.reduce(sum_func) / frame_history_cpu.size() + frame_history_cpu_avg.text = str(frametime_cpu_avg).pad_decimals(2) + frame_history_cpu_avg.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_cpu_avg, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_cpu_min: float = frame_history_cpu.min() + frame_history_cpu_min.text = str(frametime_cpu_min).pad_decimals(2) + frame_history_cpu_min.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_cpu_min, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_cpu_max: float = frame_history_cpu.max() + frame_history_cpu_max.text = str(frametime_cpu_max).pad_decimals(2) + frame_history_cpu_max.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_cpu_max, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + frame_history_cpu_last.text = str(frametime_cpu).pad_decimals(2) + frame_history_cpu_last.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_cpu, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_gpu := RenderingServer.viewport_get_measured_render_time_gpu(viewport_rid) + frame_history_gpu.push_back(frametime_gpu) + if frame_history_gpu.size() > HISTORY_NUM_FRAMES: + frame_history_gpu.pop_front() + + frametime_gpu_avg = frame_history_gpu.reduce(sum_func) / frame_history_gpu.size() + frame_history_gpu_avg.text = str(frametime_gpu_avg).pad_decimals(2) + frame_history_gpu_avg.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_gpu_avg, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_gpu_min: float = frame_history_gpu.min() + frame_history_gpu_min.text = str(frametime_gpu_min).pad_decimals(2) + frame_history_gpu_min.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_gpu_min, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + var frametime_gpu_max: float = frame_history_gpu.max() + frame_history_gpu_max.text = str(frametime_gpu_max).pad_decimals(2) + frame_history_gpu_max.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_gpu_max, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + frame_history_gpu_last.text = str(frametime_gpu).pad_decimals(2) + frame_history_gpu_last.modulate = frame_time_gradient.sample(remap(1000.0 / frametime_gpu, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + + frames_per_second = 1000.0 / frametime_avg + fps_history.push_back(frames_per_second) + if fps_history.size() > HISTORY_NUM_FRAMES: + fps_history.pop_front() + + fps.text = str(floor(frames_per_second)) + " FPS" + var frame_time_color := frame_time_gradient.sample(remap(frames_per_second, GRAPH_MIN_FPS, GRAPH_MAX_FPS, 0.0, 1.0)) + fps.modulate = frame_time_color + + frame_time.text = str(frametime).pad_decimals(2) + " mspf" + frame_time.modulate = frame_time_color + + var vsync_string := "" + match DisplayServer.window_get_vsync_mode(): + DisplayServer.VSYNC_ENABLED: + vsync_string = "V-Sync" + DisplayServer.VSYNC_ADAPTIVE: + vsync_string = "Adaptive V-Sync" + DisplayServer.VSYNC_MAILBOX: + vsync_string = "Mailbox V-Sync" + + if Engine.max_fps > 0 or OS.low_processor_usage_mode: + # Display FPS cap determined by `Engine.max_fps` or low-processor usage mode sleep duration + # (the lowest FPS cap is used). + var low_processor_max_fps := roundi(1000000.0 / OS.low_processor_usage_mode_sleep_usec) + var fps_cap := low_processor_max_fps + if Engine.max_fps > 0: + fps_cap = mini(Engine.max_fps, low_processor_max_fps) + frame_time.text += " (cap: " + str(fps_cap) + " FPS" + + if not vsync_string.is_empty(): + frame_time.text += " + " + vsync_string + + frame_time.text += ")" + else: + if not vsync_string.is_empty(): + frame_time.text += " (" + vsync_string + ")" + + frame_number.text = "Frame: " + str(Engine.get_frames_drawn()) + + last_tick = Time.get_ticks_usec() + + +func _on_visibility_changed() -> void: + if visible: + # Reset graphs to prevent them from looking strange before `HISTORY_NUM_FRAMES` frames + # have been drawn. + var frametime_last := (Time.get_ticks_usec() - last_tick) * 0.001 + fps_history.resize(HISTORY_NUM_FRAMES) + fps_history.fill(1000.0 / frametime_last) + frame_history_total.resize(HISTORY_NUM_FRAMES) + frame_history_total.fill(frametime_last) + frame_history_cpu.resize(HISTORY_NUM_FRAMES) + var viewport_rid := get_viewport().get_viewport_rid() + frame_history_cpu.fill(RenderingServer.viewport_get_measured_render_time_cpu(viewport_rid) + RenderingServer.get_frame_setup_time_cpu()) + frame_history_gpu.resize(HISTORY_NUM_FRAMES) + frame_history_gpu.fill(RenderingServer.viewport_get_measured_render_time_gpu(viewport_rid)) diff --git a/scenes/load/console/debug_menu/debug_menu.gd.uid b/scenes/load/console/debug_menu/debug_menu.gd.uid new file mode 100644 index 0000000..472c086 --- /dev/null +++ b/scenes/load/console/debug_menu/debug_menu.gd.uid @@ -0,0 +1 @@ +uid://5w03cxb435ih diff --git a/scenes/load/console/debug_menu/debug_menu.tscn b/scenes/load/console/debug_menu/debug_menu.tscn new file mode 100644 index 0000000..0dbd9bc --- /dev/null +++ b/scenes/load/console/debug_menu/debug_menu.tscn @@ -0,0 +1,398 @@ +[gd_scene load_steps=3 format=3 uid="uid://cggqb75a8w8r"] + +[ext_resource type="Script" uid="uid://5w03cxb435ih" path="res://load/console/debug_menu/debug_menu.gd" id="1_p440y"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ki0n8"] +bg_color = Color(0, 0, 0, 0.25098) + +[node name="DebugMenu" type="Control" node_paths=PackedStringArray("fps", "frame_time", "frame_number", "frame_history_total_avg", "frame_history_total_min", "frame_history_total_max", "frame_history_total_last", "frame_history_cpu_avg", "frame_history_cpu_min", "frame_history_cpu_max", "frame_history_cpu_last", "frame_history_gpu_avg", "frame_history_gpu_min", "frame_history_gpu_max", "frame_history_gpu_last", "fps_graph", "total_graph", "cpu_graph", "gpu_graph", "information", "settings")] +custom_minimum_size = Vector2(400, 400) +layout_mode = 3 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -416.0 +offset_top = 8.0 +offset_right = -16.0 +offset_bottom = 408.0 +grow_horizontal = 0 +size_flags_horizontal = 8 +size_flags_vertical = 4 +mouse_filter = 2 +script = ExtResource("1_p440y") +fps = NodePath("VBoxContainer/FPS") +frame_time = NodePath("VBoxContainer/FrameTime") +frame_number = NodePath("VBoxContainer/FrameNumber") +frame_history_total_avg = NodePath("VBoxContainer/FrameTimeHistory/AvgHeader") +frame_history_total_min = NodePath("VBoxContainer/FrameTimeHistory/MinHeader") +frame_history_total_max = NodePath("VBoxContainer/FrameTimeHistory/MaxHeader") +frame_history_total_last = NodePath("VBoxContainer/FrameTimeHistory/LastHeader") +frame_history_cpu_avg = NodePath("VBoxContainer/FrameTimeHistory/TotalAvg") +frame_history_cpu_min = NodePath("VBoxContainer/FrameTimeHistory/TotalMin") +frame_history_cpu_max = NodePath("VBoxContainer/FrameTimeHistory/TotalMax") +frame_history_cpu_last = NodePath("VBoxContainer/FrameTimeHistory/TotalLast") +frame_history_gpu_avg = NodePath("VBoxContainer/FrameTimeHistory/GPUHeader") +frame_history_gpu_min = NodePath("VBoxContainer/FrameTimeHistory/GPUMin") +frame_history_gpu_max = NodePath("VBoxContainer/FrameTimeHistory/GPUMax") +frame_history_gpu_last = NodePath("VBoxContainer/FrameTimeHistory/GPULast") +fps_graph = NodePath("VBoxContainer/FPSGraph/Graph") +total_graph = NodePath("VBoxContainer/TotalGraph/Graph") +cpu_graph = NodePath("VBoxContainer/CPUGraph/Graph") +gpu_graph = NodePath("VBoxContainer/GPUGraph/Graph") +information = NodePath("VBoxContainer/Information") +settings = NodePath("VBoxContainer/Settings") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -300.0 +offset_bottom = 374.0 +grow_horizontal = 0 +mouse_filter = 2 +theme_override_constants/separation = 0 + +[node name="FPS" type="Label" parent="VBoxContainer"] +modulate = Color(0, 1, 0, 1) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/line_spacing = 0 +theme_override_constants/outline_size = 5 +theme_override_font_sizes/font_size = 18 +text = "60 FPS" +horizontal_alignment = 2 + +[node name="FrameTime" type="Label" parent="VBoxContainer"] +modulate = Color(0, 1, 0, 1) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "16.67 mspf (cap: 123 FPS + Adaptive V-Sync)" +horizontal_alignment = 2 + +[node name="FrameNumber" type="Label" parent="VBoxContainer"] +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Frame: 1234" +horizontal_alignment = 2 + +[node name="FrameTimeHistory" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 8 +mouse_filter = 2 +theme_override_constants/h_separation = 0 +theme_override_constants/v_separation = 0 +columns = 5 + +[node name="Spacer" type="Control" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 +mouse_filter = 2 + +[node name="AvgHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Average" +horizontal_alignment = 2 + +[node name="MinHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Best" +horizontal_alignment = 2 + +[node name="MaxHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Worst" +horizontal_alignment = 2 + +[node name="LastHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Last" +horizontal_alignment = 2 + +[node name="TotalHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Total:" +horizontal_alignment = 2 + +[node name="TotalAvg" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="TotalMin" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="TotalMax" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="TotalLast" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="CPUHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "CPU:" +horizontal_alignment = 2 + +[node name="CPUAvg" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="CPUMin" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "12.34" +horizontal_alignment = 2 + +[node name="CPUMax" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="CPULast" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="GPUHeader" type="Label" parent="VBoxContainer/FrameTimeHistory"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "GPU:" +horizontal_alignment = 2 + +[node name="GPUAvg" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="GPUMin" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "1.23" +horizontal_alignment = 2 + +[node name="GPUMax" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="GPULast" type="Label" parent="VBoxContainer/FrameTimeHistory"] +modulate = Color(0, 1, 0, 1) +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "123.45" +horizontal_alignment = 2 + +[node name="FPSGraph" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +mouse_filter = 2 +alignment = 2 + +[node name="Title" type="Label" parent="VBoxContainer/FPSGraph"] +custom_minimum_size = Vector2(0, 27) +layout_mode = 2 +size_flags_horizontal = 8 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "FPS: ↑" +vertical_alignment = 1 + +[node name="Graph" type="Panel" parent="VBoxContainer/FPSGraph"] +custom_minimum_size = Vector2(150, 25) +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_ki0n8") + +[node name="TotalGraph" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +mouse_filter = 2 +alignment = 2 + +[node name="Title" type="Label" parent="VBoxContainer/TotalGraph"] +custom_minimum_size = Vector2(0, 27) +layout_mode = 2 +size_flags_horizontal = 8 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Total: ↓" +vertical_alignment = 1 + +[node name="Graph" type="Panel" parent="VBoxContainer/TotalGraph"] +custom_minimum_size = Vector2(150, 25) +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_ki0n8") + +[node name="CPUGraph" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +mouse_filter = 2 +alignment = 2 + +[node name="Title" type="Label" parent="VBoxContainer/CPUGraph"] +custom_minimum_size = Vector2(0, 27) +layout_mode = 2 +size_flags_horizontal = 8 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "CPU: ↓" +vertical_alignment = 1 + +[node name="Graph" type="Panel" parent="VBoxContainer/CPUGraph"] +custom_minimum_size = Vector2(150, 25) +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_ki0n8") + +[node name="GPUGraph" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +mouse_filter = 2 +alignment = 2 + +[node name="Title" type="Label" parent="VBoxContainer/GPUGraph"] +custom_minimum_size = Vector2(0, 27) +layout_mode = 2 +size_flags_horizontal = 8 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "GPU: ↓" +vertical_alignment = 1 + +[node name="Graph" type="Panel" parent="VBoxContainer/GPUGraph"] +custom_minimum_size = Vector2(150, 25) +layout_mode = 2 +size_flags_vertical = 0 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_ki0n8") + +[node name="Information" type="Label" parent="VBoxContainer"] +modulate = Color(1, 1, 1, 0.752941) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "12th Gen Intel(R) Core(TM) i0-1234K +Windows 12 64-bit (double precision), Vulkan 1.2.34 +NVIDIA GeForce RTX 1234, 123.45.67" +horizontal_alignment = 2 + +[node name="Settings" type="Label" parent="VBoxContainer"] +modulate = Color(0.8, 0.84, 1, 0.752941) +layout_mode = 2 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 3 +theme_override_font_sizes/font_size = 12 +text = "Project Version: 1.2.3 +Rendering Method: Forward+ +Window: 1234×567, Viewport: 1234×567 +3D Scale (FSR 1.0): 100% = 1234×567 +3D Antialiasing: TAA + 2× MSAA + FXAA +SSR: 123 Steps +SSAO: On +SSIL: On +SDFGI: 1 Cascades +Glow: On +Volumetric Fog: On +2D Antialiasing: 2× MSAA" +horizontal_alignment = 2 + +[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"] diff --git a/scenes/load/game.gd b/scenes/load/game.gd new file mode 100644 index 0000000..f0d021b --- /dev/null +++ b/scenes/load/game.gd @@ -0,0 +1,13 @@ +extends Node + +func lerp_toward(current, target, speed: float, delta: float): + return current + (target - current) * (1.0 - exp(-speed * delta)) + +func lerp_toward_angle(current: float, target: float, speed: float, delta: float) -> float: + var difference = wrapf(target - current, -PI, PI) + return current + difference * (1.0 - exp(-speed * delta)) + +func move_toward_angle(from : float, to: float, delta : float): + var ans = fposmod(to - from, TAU) + if ans > PI: ans -= TAU + return from + ans * delta diff --git a/scenes/load/game.gd.uid b/scenes/load/game.gd.uid new file mode 100644 index 0000000..b7f6ffd --- /dev/null +++ b/scenes/load/game.gd.uid @@ -0,0 +1 @@ +uid://bvdc141jjl45c diff --git a/scenes/load/game_settings.gd b/scenes/load/game_settings.gd new file mode 100644 index 0000000..8059b48 --- /dev/null +++ b/scenes/load/game_settings.gd @@ -0,0 +1,19 @@ +extends Node + +var mouse_sens := 1.75 +var toggle_crouch:=false +var stick_sens := 0.15 +var stick_smoothing := 0.25 +var stick_deadzone := 0.25 +var using_gamedpad:=false: + set(is_true): + if using_gamedpad != is_true: + using_gamedpad = is_true + controller_changed.emit() +signal controller_changed + +func _input(event: InputEvent) -> void: + if event is InputEventMouseButton or event is InputEventMouseMotion or event is InputEventKey: + using_gamedpad = false + elif event is InputEventJoypadButton or event is InputEventJoypadMotion: + using_gamedpad = true diff --git a/scenes/load/game_settings.gd.uid b/scenes/load/game_settings.gd.uid new file mode 100644 index 0000000..e7a19f6 --- /dev/null +++ b/scenes/load/game_settings.gd.uid @@ -0,0 +1 @@ +uid://hhhyrxuvf73t diff --git a/scenes/load/world.tscn b/scenes/load/world.tscn new file mode 100644 index 0000000..7951ba0 --- /dev/null +++ b/scenes/load/world.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=4 format=3 uid="uid://dk7oodthk2rt2"] + +[ext_resource type="PackedScene" uid="uid://blm3k1grnn01j" path="res://scenes/player/player.tscn" id="1_g33ix"] +[ext_resource type="PackedScene" uid="uid://c5nhw4y7f37ll" path="res://scenes/level0.tscn" id="2_whu81"] +[ext_resource type="PackedScene" uid="uid://dp0qvvwtqxt5r" path="res://scenes/load/console/console.tscn" id="3_whu81"] + +[node name="world" type="Node"] + +[node name="player" parent="." instance=ExtResource("1_g33ix")] + +[node name="level0" parent="." instance=ExtResource("2_whu81")] + +[node name="console" parent="." instance=ExtResource("3_whu81")] diff --git a/scenes/player/head.gd b/scenes/player/head.gd new file mode 100644 index 0000000..8033e8a --- /dev/null +++ b/scenes/player/head.gd @@ -0,0 +1,19 @@ +extends Node3D + +@export var headbob_frequency = 3.5 +@export var headbob_amplitude = 0.01 +var _headbob_time:float + +func _physics_process(delta: float) -> void: + var headbob = _head_bob(delta) as Vector3 + %eyes.position = headbob + +func _head_bob(delta)->Vector3: + var headbob_vector:Vector3 + var time_multipliers = owner.spedometer * float(owner.is_on_floor()) + var speed_normal = owner.spedometer/owner.mult_speed + _headbob_time += delta * time_multipliers + headbob_vector.y = cos(_headbob_time*headbob_frequency)*headbob_amplitude + headbob_vector.x = sin(_headbob_time*headbob_frequency/2)*headbob_amplitude + var result = Vector3.ZERO.lerp(headbob_vector, speed_normal) + return result diff --git a/scenes/player/head.gd.uid b/scenes/player/head.gd.uid new file mode 100644 index 0000000..27a1a87 --- /dev/null +++ b/scenes/player/head.gd.uid @@ -0,0 +1 @@ +uid://da0nthck8novp diff --git a/scenes/player/player.gd b/scenes/player/player.gd new file mode 100644 index 0000000..447a0e6 --- /dev/null +++ b/scenes/player/player.gd @@ -0,0 +1,97 @@ +extends CharacterBody3D + +#region Variables +@export var desired_jump_height : float = 1.0 +@export var gravity_multiplier : float = 2.0 +@onready var collision: CollisionShape3D = $collision +@onready var neck: Node3D = $head/neck +signal fallen +signal camera_rotated(rotation_vector:Vector2) +var jump_vel: float +var _gamepad_look_vector:Vector2 +var _collison_height_origin := 0.0 +var input_dir:Vector2 +var mult_speed:=3.75 +var friction = 8 +var spedometer:float +#endregion + +#region Private Variables +func _ready(): + #------------------------------------------------Set gravity + var default_gravity = ProjectSettings.get_setting("physics/3d/default_gravity")*gravity_multiplier + jump_vel = sqrt(2 * default_gravity * desired_jump_height) + _collison_height_origin = collision.shape.height + #------------------------------------------------Set mouse + Input.set_use_accumulated_input(false) + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + +func _unhandled_input(event): + if event is InputEventMouseMotion and not GameSettings.using_gamedpad \ + and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: + _rotate_player(_gather_mouse_input(event)) + +func _rotate_player(motion:Vector2): + if motion == Vector2.ZERO: return + camera_rotated.emit(motion) + %head.rotate_y(motion.x) + collision.rotation.y = %head.rotation.y + neck.rotate_x(motion.y) + const mouseLimit = deg_to_rad(80) + neck.rotation.x = clamp(neck.rotation.x, -mouseLimit, mouseLimit) + +func _locomotion(delta): + input_dir = Input.get_vector("left", "right", "up", "down", GameSettings.stick_deadzone) + var direction = (%head.global_basis * Vector3(input_dir.x, 0, input_dir.y)) + if direction: + velocity.x = Game.lerp_toward(velocity.x, direction.x*mult_speed,friction,delta) + velocity.z = Game.lerp_toward(velocity.z, direction.z*mult_speed,friction,delta) + else: + velocity.x = Game.lerp_toward(velocity.x, 0.0, friction, delta) + velocity.z = Game.lerp_toward(velocity.z, 0.0, friction, delta) + +func _gather_mouse_input(event: InputEventMouseMotion) -> Vector2: + var viewport_size = get_viewport().get_visible_rect().size + var normalized_input = event.relative / viewport_size.length() + normalized_input *= GameSettings.mouse_sens + return -normalized_input + +func _gather_stick_input(delta): + var input_vector = Input.get_vector("look_right", "look_left", "look_down", "look_up", + GameSettings.stick_deadzone) + var sens_intepolated = lerpf(0.001, 0.1,GameSettings.stick_sens) + input_vector *= sens_intepolated + var smooting_interpolated = lerpf(20,2,GameSettings.stick_smoothing) + _gamepad_look_vector = Game.lerp_toward(_gamepad_look_vector, input_vector,smooting_interpolated, delta) + _rotate_player(input_vector if GameSettings.stick_smoothing == 0.0 else _gamepad_look_vector) + +func _recrouch(height:float): + collision.shape.height = height + collision.position.y = collision.shape.height/2 + +func _process(delta: float) -> void: + if GameSettings.using_gamedpad: _gather_stick_input(delta) +func _physics_process(delta): + #------------------------------------------------Jumping + if Input.is_action_just_pressed("jump") and is_on_floor(): + velocity.y += jump_vel + #------------------------------------------------Movement + _locomotion(delta) + _move_and_check(delta) + +func _move_and_check(delta): + #------------------------------------------------Gravity + if is_on_floor(): friction = 8 + else: + var gravity = get_gravity().y*gravity_multiplier + friction = 1 + velocity.y += gravity * delta + #------------------------------------------------Speed + var real_speed = get_real_velocity() + spedometer = Vector2(real_speed.x, real_speed.z).length() + #------------------------------------------------Move and Check + var prev_fall = velocity.y + move_and_slide() + if prev_fall < -10 and velocity.y >= 0: + fallen.emit() +#endregion diff --git a/scenes/player/player.gd.uid b/scenes/player/player.gd.uid new file mode 100644 index 0000000..4bdb6e2 --- /dev/null +++ b/scenes/player/player.gd.uid @@ -0,0 +1 @@ +uid://dmu4p3ty3a1bk diff --git a/scenes/player/player.tscn b/scenes/player/player.tscn new file mode 100644 index 0000000..73fa9a9 --- /dev/null +++ b/scenes/player/player.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=4 format=3 uid="uid://blm3k1grnn01j"] + +[ext_resource type="Script" uid="uid://dmu4p3ty3a1bk" path="res://scenes/player/player.gd" id="1_4flbx"] +[ext_resource type="Script" uid="uid://da0nthck8novp" path="res://scenes/player/head.gd" id="2_dovo2"] + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_75vfm"] +margin = 0.01 +height = 1.8 +radius = 0.3 + +[node name="player" type="CharacterBody3D" groups=["player"]] +collision_layer = 32772 +collision_mask = 3 +floor_block_on_wall = false +script = ExtResource("1_4flbx") + +[node name="collision" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0) +shape = SubResource("CylinderShape3D_75vfm") + +[node name="head" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.44, 0) +script = ExtResource("2_dovo2") + +[node name="neck" type="Node3D" parent="head"] + +[node name="eyes" type="Camera3D" parent="head/neck"] +unique_name_in_owner = true +cull_mask = 1048063 +current = true