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 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ 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