diff --git a/boat/WalkableBoat.gd b/boat/WalkableBoat.gd
new file mode 100644
index 0000000..8fe74bd
--- /dev/null
+++ b/boat/WalkableBoat.gd
@@ -0,0 +1,72 @@
+@icon("uid://dek4dvcv5fyh5")
+extends RigidBody3D
+class_name BoatBody3D
+
+@export var float_force := 1.0
+@export var water_drag := 0.05
+@export var water_angular_drag := 0.05
+
+@onready var gravity:float = ProjectSettings.get_setting("physics/3d/default_gravity")
+
+@onready var probes = $ProbeContainer.get_children()
+
+var submerged := false
+
+var is_docked: bool = false
+
+@onready var ocean : Ocean = get_tree().get_nodes_in_group("ocean")[0]
+
+@export var max_thrust_force: float = 1024
+@export var max_steering: float = 128
+
+var steering: float = 0 # steering rudder angle in radians
+var thrust_force: float = 0 # forward thrust force in Newtons
+
+
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ add_to_group("boats")
+
+
+
+func _physics_process(delta):
+ submerged = false
+ for p in probes:
+ var depth = ocean.get_water_level(p.global_position) - p.global_position.y
+ if depth > 0:
+ submerged = true
+ apply_force(Vector3.UP * float_force * gravity * depth, p.global_position - global_position)
+
+ apply_central_force(-self.global_transform.basis.z.normalized() * Vector3(1, 0, 1) * thrust_force)
+ apply_torque(Vector3.UP * steering)
+
+ ##apply_torque(-global_transform.basis.z.normalized() * steering * 0.05) # for sideways motion
+
+ print("Submerged" + str(submerged))
+ reset_forces()
+
+func _integrate_forces(state: PhysicsDirectBodyState3D):
+ if submerged:
+ state.linear_velocity *= 1 - water_drag
+ state.angular_velocity *= 1 - water_angular_drag
+
+
+
+func thrust():
+ if not is_docked:
+ thrust_force = max_thrust_force
+
+func steer_right():
+ if not is_docked:
+ steering = -PI * max_steering
+
+func steer_left():
+ if not is_docked:
+ steering = PI * max_steering
+
+
+func reset_forces():
+ thrust_force = 0
+ steering = 0
diff --git a/boat/WalkableBoat.gd.uid b/boat/WalkableBoat.gd.uid
new file mode 100644
index 0000000..b2be4a7
--- /dev/null
+++ b/boat/WalkableBoat.gd.uid
@@ -0,0 +1 @@
+uid://du135dtrpwm7o
diff --git a/boat/boat.tscn b/boat/boat.tscn
index 1696e5a..ecb90a2 100644
--- a/boat/boat.tscn
+++ b/boat/boat.tscn
@@ -1,12 +1,14 @@
[gd_scene load_steps=4 format=3 uid="uid://babgqvkugifk1"]
-[ext_resource type="Script" uid="uid://crtr3lle7lx7g" path="res://boat/boat.gd" id="1_jbc2f"]
+[ext_resource type="Script" uid="uid://du135dtrpwm7o" path="res://boat/WalkableBoat.gd" id="1_ml88t"]
[ext_resource type="PackedScene" uid="uid://bcdjvsj0la72h" path="res://boat/source/untitled.fbx" id="2_enlnh"]
-[ext_resource type="Shape3D" uid="uid://jdtw7cqqrtpb" path="res://boat/model/Boat_CollisionShape.tres" id="3_ml88t"]
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_enlnh"]
+size = Vector3(1.3, 1, 1)
[node name="Boat" type="RigidBody3D"]
mass = 10.0
-script = ExtResource("1_jbc2f")
+script = ExtResource("1_ml88t")
[node name="SpringArm3D" type="SpringArm3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.893285, 0.449491, 0, -0.449491, 0.893285, 0, 0.350159, 0)
@@ -18,6 +20,16 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.107117, 0.323316, 2.70191)
[node name="untitled" parent="." instance=ExtResource("2_enlnh")]
transform = Transform3D(-0.1, 0, -1.50996e-08, 0, 0.1, 0, 1.50996e-08, 0, -0.1, 0, -0.169637, 0)
-[node name="BoatCollision" type="CollisionShape3D" parent="."]
-transform = Transform3D(-10, 8.74228e-07, 3.82137e-14, 0, -4.37114e-07, 10, 8.74228e-07, 10, 4.37114e-07, -0.179, 0.151184, 0)
-shape = ExtResource("3_ml88t")
+[node name="ProbeContainer" type="Node3D" parent="."]
+
+[node name="Proue" type="Marker3D" parent="ProbeContainer"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.696, 0, 0)
+
+[node name="Poupe" type="Marker3D" parent="ProbeContainer"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.604, 0, 0)
+
+[node name="Cale2" type="Marker3D" parent="ProbeContainer"]
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.64117, 0)
+shape = SubResource("BoxShape3D_enlnh")
diff --git a/icons/Wave.svg b/icons/Wave.svg
new file mode 100644
index 0000000..2de990e
--- /dev/null
+++ b/icons/Wave.svg
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/icons/Wave.svg.import b/icons/Wave.svg.import
new file mode 100644
index 0000000..d958b93
--- /dev/null
+++ b/icons/Wave.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cbqveb0y8fkiv"
+path="res://.godot/imported/Wave.svg-e4e9ecbf1b0cccaba3ebe27eace1646e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icons/Wave.svg"
+dest_files=["res://.godot/imported/Wave.svg-e4e9ecbf1b0cccaba3ebe27eace1646e.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/icons/boat-svgrepo-com.svg b/icons/boat-svgrepo-com.svg
new file mode 100644
index 0000000..aa80f4f
--- /dev/null
+++ b/icons/boat-svgrepo-com.svg
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/icons/boat-svgrepo-com.svg.import b/icons/boat-svgrepo-com.svg.import
new file mode 100644
index 0000000..c80a290
--- /dev/null
+++ b/icons/boat-svgrepo-com.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dek4dvcv5fyh5"
+path="res://.godot/imported/boat-svgrepo-com.svg-86ce2999ded0262d699c16c66f34056b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icons/boat-svgrepo-com.svg"
+dest_files=["res://.godot/imported/boat-svgrepo-com.svg-86ce2999ded0262d699c16c66f34056b.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/mat/watershader.tres b/mat/watershader.tres
index 1e57d2f..7f9792f 100644
--- a/mat/watershader.tres
+++ b/mat/watershader.tres
@@ -84,7 +84,7 @@ linked_parent_graph_frame = 31
operator = 2
[sub_resource type="VisualShaderNodeFrame" id="VisualShaderNodeFrame_dt65u"]
-size = Vector2(2524, 1292)
+size = Vector2(2524, 1182)
title = "Foam"
attached_nodes = PackedInt32Array(27, 30, 24, 29, 26, 38, 23, 34, 33, 32, 35, 36, 37, 50, 53, 54, 60, 61, 58, 59, 57, 51, 52)
@@ -183,7 +183,7 @@ linked_parent_graph_frame = 49
input_name = "time"
[sub_resource type="VisualShaderNodeFrame" id="VisualShaderNodeFrame_obdjg"]
-size = Vector2(2124, 1224)
+size = Vector2(2124, 1182)
title = "Noise"
attached_nodes = PackedInt32Array(15, 17, 10, 42, 44, 45, 48, 47, 46, 8, 16, 43, 41, 22, 11, 7, 5, 62)
@@ -665,7 +665,6 @@ void fragment() {
}
"
-graph_offset = Vector2(-106.871, 138.902)
modes/diffuse = 3
modes/specular = 1
flags/fog_disabled = true
diff --git a/ocean/Ocean.tres b/ocean/Ocean.tres
new file mode 100644
index 0000000..8771111
--- /dev/null
+++ b/ocean/Ocean.tres
@@ -0,0 +1,26 @@
+[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://c8b0eq0wyy40b"]
+
+[ext_resource type="Shader" uid="uid://bded0c7emuh61" path="res://ocean/ocean.gdshader" id="1_3d3q0"]
+
+[resource]
+render_priority = 0
+shader = ExtResource("1_3d3q0")
+shader_parameter/albedo = Color(0, 0.32, 0.43, 1)
+shader_parameter/albedo2 = Color(0, 0.47, 0.76, 1)
+shader_parameter/color_deep = Color(0.11, 0.29, 0.33, 1)
+shader_parameter/color_shallow = Color(0, 0.47, 0.76, 1)
+shader_parameter/metallic = 0.0
+shader_parameter/roughness = 0.02
+shader_parameter/wave_time = 0.0
+shader_parameter/wave_direction = Vector2(0.5, -0.2)
+shader_parameter/wave_2_direction = Vector2(0, 1)
+shader_parameter/time_scale = 0.1
+shader_parameter/wave_speed = 2.0
+shader_parameter/noise_scale = 20.0
+shader_parameter/height_scale = 2.0
+shader_parameter/beers_law = 2.0
+shader_parameter/depth_offset = 1.5
+shader_parameter/edge_scale = 0.3
+shader_parameter/near = 1.0
+shader_parameter/far = 100.0
+shader_parameter/edge_color = Color(1, 1, 1, 1)
diff --git a/ocean/Ocean2.tres b/ocean/Ocean2.tres
new file mode 100644
index 0000000..f56fcfa
--- /dev/null
+++ b/ocean/Ocean2.tres
@@ -0,0 +1,64 @@
+[gd_resource type="ShaderMaterial" load_steps=8 format=3 uid="uid://djvstk5qjvdan"]
+
+[ext_resource type="Shader" uid="uid://bded0c7emuh61" path="res://ocean/ocean.gdshader" id="1_u0w43"]
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_u0w43"]
+noise_type = 3
+frequency = 0.035
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_mf4pf"]
+seamless = true
+as_normal_map = true
+bump_strength = 1.6
+noise = SubResource("FastNoiseLite_u0w43")
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_3qqsl"]
+noise_type = 0
+seed = 22
+frequency = 0.003
+fractal_lacunarity = 1.6
+fractal_gain = 0.47
+fractal_weighted_strength = 0.53
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_nojbg"]
+seamless = true
+seamless_blend_skirt = 0.532
+as_normal_map = true
+bump_strength = 21.8
+noise = SubResource("FastNoiseLite_3qqsl")
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_xta2c"]
+noise_type = 2
+fractal_type = 2
+fractal_gain = 0.34
+fractal_weighted_strength = 0.6
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_0vxpe"]
+seamless = true
+noise = SubResource("FastNoiseLite_xta2c")
+
+[resource]
+render_priority = 0
+shader = ExtResource("1_u0w43")
+shader_parameter/albedo = Color(0, 0.32, 0.43, 1)
+shader_parameter/albedo2 = Color(0, 0.47, 0.76, 1)
+shader_parameter/color_deep = Color(0.11, 0.29, 0.33, 1)
+shader_parameter/color_shallow = Color(0, 0.47, 0.76, 1)
+shader_parameter/metallic = 0.0
+shader_parameter/roughness = 0.02
+shader_parameter/texture_normal = SubResource("NoiseTexture2D_mf4pf")
+shader_parameter/texture_normal2 = SubResource("NoiseTexture2D_nojbg")
+shader_parameter/wave = SubResource("NoiseTexture2D_0vxpe")
+shader_parameter/wave_time = 7.905
+shader_parameter/wave_direction = Vector2(2, 0)
+shader_parameter/wave_2_direction = Vector2(0, 1)
+shader_parameter/time_scale = 0.025
+shader_parameter/wave_speed = 0.06
+shader_parameter/noise_scale = 5.005
+shader_parameter/height_scale = 0.16
+shader_parameter/beers_law = 2.0
+shader_parameter/depth_offset = -0.75
+shader_parameter/edge_scale = 0.1
+shader_parameter/near = 0.5
+shader_parameter/far = 100.0
+shader_parameter/edge_color = Color(0.111197, 0.111197, 0.111197, 1)
diff --git a/ocean/Ocean_playground.tscn b/ocean/Ocean_playground.tscn
new file mode 100644
index 0000000..711dbd8
--- /dev/null
+++ b/ocean/Ocean_playground.tscn
@@ -0,0 +1,43 @@
+[gd_scene load_steps=8 format=3 uid="uid://hs3a438it6j6"]
+
+[ext_resource type="Material" uid="uid://djvstk5qjvdan" path="res://ocean/Ocean2.tres" id="1_kiaws"]
+[ext_resource type="Script" uid="uid://c12fpc7inp27s" path="res://ocean/ocean.gd" id="2_ap626"]
+[ext_resource type="PackedScene" uid="uid://babgqvkugifk1" path="res://boat/boat.tscn" id="3_ap626"]
+
+[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_kiaws"]
+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_ap626"]
+sky_material = SubResource("ProceduralSkyMaterial_kiaws")
+
+[sub_resource type="Environment" id="Environment_2qsx7"]
+background_mode = 2
+sky = SubResource("Sky_ap626")
+tonemap_mode = 2
+glow_enabled = true
+
+[sub_resource type="PlaneMesh" id="PlaneMesh_mf4pf"]
+material = ExtResource("1_kiaws")
+size = Vector2(10, 10)
+subdivide_width = 100
+subdivide_depth = 100
+
+[node name="Node3D" type="Node3D"]
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_2qsx7")
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
+shadow_enabled = true
+
+[node name="Ocean" type="Node3D" parent="."]
+
+[node name="Water_Tile_01" type="MeshInstance3D" parent="Ocean"]
+mesh = SubResource("PlaneMesh_mf4pf")
+skeleton = NodePath("../..")
+script = ExtResource("2_ap626")
+
+[node name="Boat" parent="." instance=ExtResource("3_ap626")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.236798, 0)
diff --git a/ocean/ocean.gd b/ocean/ocean.gd
new file mode 100644
index 0000000..2e20aec
--- /dev/null
+++ b/ocean/ocean.gd
@@ -0,0 +1,34 @@
+@icon("uid://cbqveb0y8fkiv")
+extends MeshInstance3D
+class_name Ocean
+
+var material: ShaderMaterial
+var noise: Image
+
+var noise_scale: float
+var wave_speed: float
+var height_scale: float
+
+var time: float
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ add_to_group("ocean")
+ material = mesh.surface_get_material(0)
+ if material != null:
+ noise = material.get_shader_parameter("wave").noise.get_seamless_image(512, 512)
+ noise_scale = material.get_shader_parameter("noise_scale")
+ wave_speed = material.get_shader_parameter("wave_speed")
+ height_scale = material.get_shader_parameter("height_scale")
+
+ # Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+ time += delta
+ material.set_shader_parameter("wave_time", time)
+
+func get_water_level(world_position: Vector3) -> float:
+ var uv_x = wrapf(world_position.x / noise_scale + time * wave_speed, 0, 1)
+ var uv_y = wrapf(world_position.z / noise_scale + time * wave_speed, 0, 1)
+
+ var pixel_pos = Vector2(uv_x * noise.get_width(), uv_y * noise.get_height())
+ return global_position.y + noise.get_pixelv(pixel_pos).r * height_scale;
diff --git a/ocean/ocean.gd.uid b/ocean/ocean.gd.uid
new file mode 100644
index 0000000..2f81358
--- /dev/null
+++ b/ocean/ocean.gd.uid
@@ -0,0 +1 @@
+uid://c12fpc7inp27s
diff --git a/ocean/ocean.gdshader b/ocean/ocean.gdshader
new file mode 100644
index 0000000..33362cd
--- /dev/null
+++ b/ocean/ocean.gdshader
@@ -0,0 +1,81 @@
+shader_type spatial;
+render_mode depth_draw_always;
+
+uniform sampler2D SCREEN_TEXTURE: hint_screen_texture, filter_linear_mipmap;
+uniform sampler2D DEPTH_TEXTURE: hint_depth_texture, filter_linear_mipmap;
+
+uniform vec3 albedo : source_color = vec3(0.0,0.32,0.43);
+uniform vec3 albedo2 : source_color= vec3(0.0,0.47,0.76);
+uniform vec4 color_deep : source_color= vec4(0.11,0.29,0.33,1.0);
+uniform vec4 color_shallow : source_color= vec4(0.0,0.47,0.76,1.0);
+
+uniform float metallic : hint_range(0.0, 1.0) = 0;
+uniform float roughness : hint_range(0.0, 1.0) = 0.02;
+
+uniform sampler2D texture_normal;
+uniform sampler2D texture_normal2;
+uniform sampler2D wave;
+
+uniform float wave_time = 0;
+uniform vec2 wave_direction = vec2(2.0,0.0);
+uniform vec2 wave_2_direction = vec2(0.0,1.0);
+uniform float time_scale : hint_range(0.0, 0.2, 0.005) = 0.025;
+uniform float wave_speed = 2.0;
+uniform float noise_scale = 10.0;
+uniform float height_scale = 0.15;
+uniform float beers_law = 2.0;
+uniform float depth_offset = -0.75;
+
+varying float height;
+varying vec3 world_pos;
+
+uniform float edge_scale = 0.1;
+uniform float near = 0.5;
+uniform float far = 100.0;
+uniform vec3 edge_color : source_color;
+
+float fresnel(float amount, vec3 normal, vec3 view)
+{
+ return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0 )), amount);
+}
+
+float edge(float depth) {
+ return near * far / (far + depth * (near - far));
+}
+
+void vertex() {
+ world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
+ height = texture(wave, world_pos.xz / noise_scale + wave_time * wave_speed).r;
+ VERTEX.y += height * height_scale;
+}
+
+void fragment() {
+ float depth_texture = texture(DEPTH_TEXTURE, SCREEN_UV).r;
+ float depth = PROJECTION_MATRIX[3][2] / (depth_texture + PROJECTION_MATRIX[2][2]);
+ depth = depth + VERTEX.z;
+ float depth_blend = exp((depth + depth_offset) * -beers_law);
+ depth_blend = clamp(1.0 - depth_blend, 0.0, 1.0);
+
+ vec3 screen_color = textureLod(SCREEN_TEXTURE, SCREEN_UV, depth_blend * 2.5).rgb;
+ vec3 depth_color = mix(color_shallow.rgb, color_deep.rgb, depth_blend);
+ vec3 color = mix(screen_color * depth_color, depth_color * 0.25, depth_blend * 0.5);
+
+ float z_depth = edge(texture(DEPTH_TEXTURE, SCREEN_UV).x);
+ float z_pos = edge(FRAGCOORD.z);
+ float z_dif = z_depth - z_pos;
+
+ vec2 time = (TIME * wave_direction) * time_scale;
+ vec2 time2 = (TIME * wave_2_direction) * time_scale;
+
+ vec3 normal_blend = mix(texture(texture_normal, world_pos.xz / noise_scale + time).rgb, texture(texture_normal2, world_pos.xz / noise_scale + time2).rgb, 0.5);
+
+ float fresnel = fresnel(5.0, NORMAL, VIEW);
+ vec3 surface_color = mix(albedo, albedo2, fresnel);
+ vec3 depth_color_adj = mix(edge_color, color, step(edge_scale, z_dif));
+
+ ALBEDO = clamp(surface_color + depth_color_adj,vec3(0),vec3(1.0));
+ ALPHA = 1.0;
+ METALLIC = metallic;
+ ROUGHNESS = roughness;
+ NORMAL_MAP = normal_blend;
+}
\ No newline at end of file
diff --git a/ocean/ocean.gdshader.uid b/ocean/ocean.gdshader.uid
new file mode 100644
index 0000000..fb31282
--- /dev/null
+++ b/ocean/ocean.gdshader.uid
@@ -0,0 +1 @@
+uid://bded0c7emuh61