shader_type spatial; render_mode blend_mix, depth_draw_always; // --- PARAMETRI COLORI ACQUA --- uniform vec4 deep_water_color : source_color = vec4(0.0, 0.1, 0.2, 1.0); uniform vec4 shallow_water_color : source_color = vec4(0.0, 0.4, 0.7, 1.0); uniform float beer_law_factor : hint_range(0.0, 5.0) = 2.0; // --- PARAMETRI SCHIUMA (DIVISI) --- uniform vec4 shore_foam_color : source_color = vec4(1.0, 1.0, 1.0, 1.0); // Schiuma che tocca gli oggetti uniform vec4 crest_foam_color : source_color = vec4(0.9, 0.95, 1.0, 1.0); // Schiuma sulle punte delle onde uniform float shore_foam_distance : hint_range(0.0, 5.0) = 0.5; // Slider aumentato a 5.0 // --- PARAMETRI ONDE 3D --- uniform float wave_rotation : hint_range(0.0, 6.28) = 0.0; uniform float wave_height : hint_range(0.0, 2.0) = 0.4; uniform float wave_frequency = 4.0; uniform float wave_speed = 2.0; uniform float wave_distortion : hint_range(0.0, 2.0) = 0.5; // --- PARAMETRI NOISE E DEPTH --- uniform sampler2D noise_texture : hint_default_white; uniform sampler2D depth_texture : hint_depth_texture, filter_linear_mipmap; varying float height_varying; varying vec2 world_pos; void vertex() { world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xz; // 1. ROTAZIONE vec2 rotated_pos = vec2( world_pos.x * cos(wave_rotation) - world_pos.y * sin(wave_rotation), world_pos.x * sin(wave_rotation) + world_pos.y * cos(wave_rotation) ); // 2. CALCOLO ONDA float noise = texture(noise_texture, world_pos * 0.05 + TIME * 0.02).r; float wave = sin(rotated_pos.y * wave_frequency + TIME * wave_speed + (noise * wave_distortion * 5.0)); height_varying = (wave + 1.0) * 0.5; VERTEX.y += wave * wave_height; } void fragment() { // --- LOGICA PROFONDITÀ --- float depth = texture(depth_texture, SCREEN_UV).r; vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth); vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0); view.xyz /= view.w; float linear_depth = -view.z; float depth_difference = linear_depth + VERTEX.z; float water_depth_gradient = exp(-depth_difference * beer_law_factor); vec4 base_water = mix(deep_water_color, shallow_water_color, water_depth_gradient); // --- GRADIENTE CRESTE --- float crest_blend = smoothstep(0.4, 0.9, height_varying); vec4 water_with_crests = mix(base_water, shallow_water_color * 1.3, crest_blend); // --- CALCOLO SCHIUMA SEPARATA --- float noise_f = texture(noise_texture, world_pos * 0.1 + TIME * 0.1).r; // 1. Schiuma a riva (Shoreline) float edge_foam_mask = smoothstep(shore_foam_distance * noise_f + 0.1, shore_foam_distance * noise_f, depth_difference); // 2. Schiuma sulla cresta (Waves) float crest_foam_mask = smoothstep(0.8, 0.95, height_varying) * 0.8; // --- MIX FINALE DEI COLORI --- // Applichiamo prima la schiuma delle onde vec3 color_with_waves = mix(water_with_crests.rgb, crest_foam_color.rgb, crest_foam_mask); // Poi applichiamo la schiuma di riva sopra a tutto vec3 final_rgb = mix(color_with_waves, shore_foam_color.rgb, edge_foam_mask); // --- OUTPUT --- ALBEDO = final_rgb; ALPHA = mix(0.98, 0.4, water_depth_gradient); // Aggiungiamo un po' di opacità extra dove c'è la schiuma di riva ALPHA = clamp(ALPHA + edge_foam_mask, 0.0, 1.0); ROUGHNESS = 0.2; SPECULAR = 0.5; }