diff --git a/asset_dev/guard_rail/guard_rail.blend b/asset_dev/guard_rail/guard_rail.blend new file mode 100644 index 0000000..19f2262 --- /dev/null +++ b/asset_dev/guard_rail/guard_rail.blend @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b579dcf9bb29390d1ed232689ffcce7e8460819f048950443596ffdc33bcb204 +size 935616 diff --git a/asset_dev/guard_rail/guard_rail_post.xcf b/asset_dev/guard_rail/guard_rail_post.xcf new file mode 100644 index 0000000..428e554 Binary files /dev/null and b/asset_dev/guard_rail/guard_rail_post.xcf differ diff --git a/assets/textures/guard_rail/guard_rail_post.png b/assets/textures/guard_rail/guard_rail_post.png new file mode 100644 index 0000000..b40cbd3 --- /dev/null +++ b/assets/textures/guard_rail/guard_rail_post.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0550d8edf85586dd8a52aa81a18befb613e41a1f405275200ad20b2ce016fd8e +size 649 diff --git a/assets/textures/guard_rail/guard_rail_post.png.import b/assets/textures/guard_rail/guard_rail_post.png.import new file mode 100644 index 0000000..d4cbfbf --- /dev/null +++ b/assets/textures/guard_rail/guard_rail_post.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cxeela02ysscf" +path="res://.godot/imported/guard_rail_post.png-4447ff881a5916e5281ed251b7beecd0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/textures/guard_rail/guard_rail_post.png" +dest_files=["res://.godot/imported/guard_rail_post.png-4447ff881a5916e5281ed251b7beecd0.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 diff --git a/levels/debug_level/debug_level.tscn b/levels/debug_level/debug_level.tscn index e3446fa..b88ea8d 100644 --- a/levels/debug_level/debug_level.tscn +++ b/levels/debug_level/debug_level.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=38 format=3 uid="uid://bm2o3mex10v11"] +[gd_scene load_steps=40 format=3 uid="uid://bm2o3mex10v11"] [ext_resource type="Terrain3DStorage" uid="uid://bu1gewgsgc5hm" path="res://levels/debug_level/terrain_3d_storage.res" id="1_nlsu2"] [ext_resource type="Texture2D" path="res://assets/textures/grass_fairway/grass_fairway_albedo.dds" id="2_e4m27"] @@ -15,6 +15,7 @@ [ext_resource type="PackedScene" uid="uid://di7aql54lksn7" path="res://src/props/scenery/trees/palm_tree/palm_tree.tscn" id="12_sswxf"] [ext_resource type="PackedScene" uid="uid://c7l58wuuahn7w" path="res://src/props/flag/flag.tscn" id="13_6jtao"] [ext_resource type="Texture2D" uid="uid://dj60e8ri2fco" path="res://assets/models/scenery/city/concrete_building_1/concrete_building_1.png" id="14_y7s2h"] +[ext_resource type="PackedScene" uid="uid://nqar1qcun8ax" path="res://src/props/scenery/highway/guard_rail.tscn" id="16_xtxyj"] [sub_resource type="FastNoiseLite" id="FastNoiseLite_rpgb7"] noise_type = 0 @@ -163,6 +164,13 @@ albedo_color = Color(0.427451, 0.917647, 1, 1) material = SubResource("StandardMaterial3D_65jc8") size = Vector2(65536, 65536) +[sub_resource type="Curve3D" id="Curve3D_3gyu3"] +_data = { +"points": PackedVector3Array(-4.50073, 0, 25.6049, 4.501, 0, -18.73, -15.152, 0, 5.61563, -20.4021, 0, 1.25826, 20.4021, 0, -1.25826, 25.991, 0, -27.2219, -9.077, 0, -17.164, 6.41687, 0, 33.4636, 72.1845, 0, 6.57864), +"tilts": PackedFloat32Array(0, 0, 0) +} +point_count = 3 + [node name="TestLevel" type="Node3D"] [node name="Terrain3D" type="Terrain3D" parent="."] @@ -242,3 +250,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 540, 4, 452) [node name="ShotSetup" parent="Course" instance=ExtResource("8_h44v5")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 212.717, 4, 294.073) + +[node name="GuardRail" parent="." instance=ExtResource("16_xtxyj")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 211.416, 4, 288.708) +curve = SubResource("Curve3D_3gyu3") diff --git a/src/characters/gfolf_girl/gfolf_girl.tscn b/src/characters/gfolf_girl/gfolf_girl.tscn index 470ae32..7f73570 100644 --- a/src/characters/gfolf_girl/gfolf_girl.tscn +++ b/src/characters/gfolf_girl/gfolf_girl.tscn @@ -169,7 +169,7 @@ bones/23/scale = Vector3(1, 1, 1) visible = false [node name="BoneAttachment3D" type="BoneAttachment3D" parent="Armature/Skeleton3D" index="6"] -transform = Transform3D(-0.944824, 0.316851, -0.0831418, -0.326496, -0.931474, 0.160486, -0.0265942, 0.178777, 0.98353, -0.1687, 3.14973, 0.864426) +transform = Transform3D(-0.944824, 0.316851, -0.0831417, -0.326395, -0.932135, 0.156815, -0.027812, 0.1753, 0.984122, -0.1687, 3.13445, 0.86185) bone_name = "Hand.R" bone_idx = 11 diff --git a/src/player/shot_setup/shot_setup.tscn b/src/player/shot_setup/shot_setup.tscn index 070b744..017e204 100644 --- a/src/player/shot_setup/shot_setup.tscn +++ b/src/player/shot_setup/shot_setup.tscn @@ -487,7 +487,7 @@ shader_parameter/change_color_depth = true shader_parameter/target_color_depth = 6 shader_parameter/dithering = true shader_parameter/scale_resolution = true -shader_parameter/target_resolution_scale = 2 +shader_parameter/target_resolution_scale = 3 shader_parameter/enable_recolor = false [sub_resource type="Animation" id="Animation_pk1s7"] diff --git a/src/props/scenery/highway/guard_rail.gd b/src/props/scenery/highway/guard_rail.gd new file mode 100644 index 0000000..d7ed9d2 --- /dev/null +++ b/src/props/scenery/highway/guard_rail.gd @@ -0,0 +1,58 @@ +@tool +extends Path3D +## Guard rail along a curve with nicely spaced posts +## +## Ref: https://www.youtube.com/watch?v=Gfpnxg-jne4 + +## Distance between railing posts, in meters +@export var post_space := 4.0: + set(value): + if value != post_space: + _dirty = true + post_space = value + +## If enabled, always places a railing post at the end of the curve. +## Post spacing will be adjusted to accomodate. +@export var end_cap := false: + set(value): + if value != end_cap: + _dirty = true + end_cap = value + +var _dirty := false + +@onready var post_multi_mesh: MultiMeshInstance3D = $PostMultiMesh + + +func _ready() -> void: + post_multi_mesh.multimesh = post_multi_mesh.multimesh.duplicate() + + +func _update_multimesh() -> void: + if not curve: + post_multi_mesh.multimesh.instance_count = 0 + return + + var path_length := curve.get_baked_length() + var count: int = floor(path_length / post_space) + var spacing := post_space + + if end_cap: + spacing = path_length / float(count) + count += 1 + + post_multi_mesh.multimesh.instance_count = count + + for i in range(0, count): + var tx := curve.sample_baked_with_rotation(spacing * i, true, true) + post_multi_mesh.multimesh.set_instance_transform(i, tx) + + +func _process(_delta: float) -> void: + if _dirty: + _update_multimesh() + _dirty = false + + +func _on_curve_changed() -> void: + _dirty = true diff --git a/src/props/scenery/highway/guard_rail.tscn b/src/props/scenery/highway/guard_rail.tscn new file mode 100644 index 0000000..dbcd586 --- /dev/null +++ b/src/props/scenery/highway/guard_rail.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=6 format=3 uid="uid://nqar1qcun8ax"] + +[ext_resource type="Script" path="res://src/props/scenery/highway/guard_rail.gd" id="1_imntf"] + +[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_fo7j3"] +load_path = "res://.godot/imported/guard_rail_post.png-4447ff881a5916e5281ed251b7beecd0.ctex" + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_k1yjg"] +transparency = 2 +alpha_scissor_threshold = 0.5 +alpha_antialiasing_mode = 0 +albedo_texture = SubResource("CompressedTexture2D_fo7j3") +texture_filter = 4 +texture_repeat = false +billboard_mode = 2 + +[sub_resource type="PlaneMesh" id="PlaneMesh_ko4yv"] +material = SubResource("StandardMaterial3D_k1yjg") +size = Vector2(0.5, 1) +center_offset = Vector3(0, 0.5, 0) +orientation = 2 + +[sub_resource type="MultiMesh" id="MultiMesh_o7ch8"] +transform_format = 1 +mesh = SubResource("PlaneMesh_ko4yv") + +[node name="GuardRail" type="Path3D"] +script = ExtResource("1_imntf") +end_cap = true + +[node name="UpperRail" type="CSGPolygon3D" parent="."] +use_collision = true +polygon = PackedVector2Array(0, 0.8, -0.01, 0.9, 0, 1, 0.01, 0.9) +mode = 2 +path_node = NodePath("..") +path_interval_type = 0 +path_interval = 1.0 +path_simplify_angle = 0.0 +path_rotation = 2 +path_local = true +path_continuous_u = true +path_u_distance = 1.0 +path_joined = false + +[node name="LowerRail" type="CSGPolygon3D" parent="."] +use_collision = true +polygon = PackedVector2Array(0, 0.4, -0.01, 0.5, 0, 0.6, 0.01, 0.5) +mode = 2 +path_node = NodePath("..") +path_interval_type = 0 +path_interval = 1.0 +path_simplify_angle = 0.0 +path_rotation = 2 +path_local = true +path_continuous_u = true +path_u_distance = 1.0 +path_joined = false + +[node name="PostMultiMesh" type="MultiMeshInstance3D" parent="."] +multimesh = SubResource("MultiMesh_o7ch8") + +[connection signal="curve_changed" from="." to="." method="_on_curve_changed"] diff --git a/src/shaders/canvas_retro.gdshader b/src/shaders/canvas_retro.gdshader index 2696dfb..d1dbc3b 100644 --- a/src/shaders/canvas_retro.gdshader +++ b/src/shaders/canvas_retro.gdshader @@ -24,15 +24,15 @@ uniform sampler2D to_gradient: hint_default_black; int dithering_pattern(ivec2 fragcoord) { const int pattern[] = { - -4, +0, -3, +1, - +2, -2, +3, -1, - -3, +1, -4, +0, + -4, +0, -3, +1, + +2, -2, +3, -1, + -3, +1, -4, +0, +3, -1, +2, -2 }; - + int x = fragcoord.x % 4; int y = fragcoord.y % 4; - + return pattern[y * 4 + x]; } @@ -70,7 +70,7 @@ vec3 rgb2hsv(vec3 rgb) { //Converts RGB values to HSV } - return vec3(h,s,cmax); // Keep original alpha value + return vec3(h,s,cmax); // Keep original alpha value } @@ -112,18 +112,18 @@ vec3 hsv2rgb(vec3 hsv) { //Converts HSV values to RGB rgb[2] = rgb[2] + m; - return rgb; + return rgb; } void fragment() { - + vec2 iResolution = 1.0 / SCREEN_PIXEL_SIZE; vec2 q = FRAGCOORD.xy / iResolution.xy; ivec2 uv = ivec2(q); - + vec3 color = texture(screen_texture, vec2(q.x,q.y) ).xyz; - + if(scale_resolution){ uv = ivec2(FRAGCOORD.xy / float(target_resolution_scale)); color = texelFetch(screen_texture, uv * target_resolution_scale, 0).rgb; @@ -131,7 +131,7 @@ void fragment() { uv = ivec2(FRAGCOORD.xy); color = texelFetch(screen_texture, uv, 0).rgb; } - + if(enable_recolor){ vec3 hsv = rgb2hsv(color); float color_pos = (hsv.x / 360.0); @@ -145,15 +145,15 @@ void fragment() { } - + // Convert from [0.0, 1.0] range to [0, 255] range ivec3 c = ivec3(round(color * 255.0)); - + // Apply the dithering pattern if (dithering) { c += ivec3(dithering_pattern(uv)); } - + vec3 final_color; if(change_color_depth){ // Truncate from 8 bits to color_depth bits @@ -162,7 +162,7 @@ void fragment() { } else { final_color = vec3(c) / float(1 << 8); } - + // Convert back to [0.0, 1.0] range COLOR.rgb = final_color; } \ No newline at end of file diff --git a/src/world/world.tscn b/src/world/world.tscn index 42b5f21..933c31f 100644 --- a/src/world/world.tscn +++ b/src/world/world.tscn @@ -24,7 +24,9 @@ grow_vertical = 2 stretch = true [node name="SubViewport" type="SubViewport" parent="SubViewportContainer"] +handle_input_locally = false size = Vector2i(1280, 720) +render_target_update_mode = 4 [node name="Level" type="Node3D" parent="SubViewportContainer/SubViewport"]