Terrain des sites de plongée : champ de hauteur authoré, Banc du Vigilant, formes variées et rendu sous-marin #4

Open
olix21 wants to merge 47 commits from olix21/worktree-terrain-site-zone1 AGit into main
pull from: olix21/worktree-terrain-site-zone1
9 changed files with 58 additions and 23 deletions
Showing only changes of commit 34b39a8dbc - Show all commits

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

After

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 KiB

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 KiB

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 KiB

After

Width:  |  Height:  |  Size: 419 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 449 KiB

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 KiB

After

Width:  |  Height:  |  Size: 261 KiB

@@ -257,6 +257,14 @@ de contacts existant les sépare du fond.
plus haute et plus forte (62°, 1,35) avec ombres douces à 70 % d'opacité, plus haute et plus forte (62°, 1,35) avec ombres douces à 70 % d'opacité,
SSAO pour l'occlusion à l'échelle du maillage, tonemap filmique, perspective SSAO pour l'occlusion à l'échelle du maillage, tonemap filmique, perspective
aérienne et albédo du brouillard volumétrique teintés. aérienne et albédo du brouillard volumétrique teintés.
- Lumière par profondeur (même jour) : le shader atténue la lumière du jour
par Beer-Lambert spectral (absorption par canal 0,11 / 0,04 / 0,032 par
mètre, normalisée à 24 m) ; la partie scalaire réduit le soleil (fonction
`light()`, directionnelle seulement) et l'ambiance ciel (`AO`), la partie
chromatique teinte l'albédo. Les projecteurs du sous-marin ne sont pas
atténués. Plancher à 5 % pour que le pied du tombant reste lisible. Palette
GDP §18.2 obtenue de fait : vert-bleu à 24 m, bleu froid à 45 m, indigo au
pied du tombant ; ciel, brouillard et soleil (0,9, ombres 45 %) refroidis.
**État du 2026-10-06 (demande d'Olivier)** : le shader mélange sable et roche **État du 2026-10-06 (demande d'Olivier)** : le shader mélange sable et roche
par la pente à partir de 20° (sable sous 20°, roche au-dessus de 40°, fondu par la pente à partir de 20° (sable sous 20°, roche au-dessus de 40°, fondu
+11 -11
View File
@@ -4,12 +4,12 @@
[ext_resource type="Script" path="res://game/world/sites/bathymetric_terrain_actor.gd" id="2_terrain"] [ext_resource type="Script" path="res://game/world/sites/bathymetric_terrain_actor.gd" id="2_terrain"]
[sub_resource type="ProceduralSkyMaterial" id="SkyUnderwater"] [sub_resource type="ProceduralSkyMaterial" id="SkyUnderwater"]
sky_top_color = Color(0.3, 0.62, 0.64, 1) sky_top_color = Color(0.22, 0.52, 0.66, 1)
sky_horizon_color = Color(0.13, 0.36, 0.41, 1) sky_horizon_color = Color(0.09, 0.28, 0.4, 1)
sky_curve = 0.2 sky_curve = 0.2
sky_energy_multiplier = 1.0 sky_energy_multiplier = 1.0
ground_horizon_color = Color(0.11, 0.3, 0.35, 1) ground_horizon_color = Color(0.05, 0.17, 0.27, 1)
ground_bottom_color = Color(0.015, 0.05, 0.07, 1) ground_bottom_color = Color(0.01, 0.03, 0.07, 1)
ground_curve = 0.1 ground_curve = 0.1
ground_energy_multiplier = 0.6 ground_energy_multiplier = 0.6
sun_angle_max = 40.0 sun_angle_max = 40.0
@@ -26,7 +26,7 @@ background_mode = 2
sky = SubResource("SkyResource") sky = SubResource("SkyResource")
ambient_light_source = 3 ambient_light_source = 3
ambient_light_sky_contribution = 1.0 ambient_light_sky_contribution = 1.0
ambient_light_energy = 1.0 ambient_light_energy = 1.3
reflected_light_source = 1 reflected_light_source = 1
tonemap_mode = 2 tonemap_mode = 2
tonemap_exposure = 1.15 tonemap_exposure = 1.15
@@ -48,8 +48,8 @@ glow_intensity = 0.8
glow_blend_mode = 0 glow_blend_mode = 0
glow_hdr_threshold = 1.2 glow_hdr_threshold = 1.2
fog_enabled = true fog_enabled = true
fog_light_color = Color(0.1, 0.3, 0.35, 1) fog_light_color = Color(0.05, 0.18, 0.29, 1)
fog_light_energy = 0.52 fog_light_energy = 0.38
fog_sun_scatter = 0.15 fog_sun_scatter = 0.15
fog_density = 0.006 fog_density = 0.006
fog_aerial_perspective = 0.5 fog_aerial_perspective = 0.5
@@ -57,7 +57,7 @@ fog_height = -4.0
fog_height_density = 0.025 fog_height_density = 0.025
volumetric_fog_enabled = true volumetric_fog_enabled = true
volumetric_fog_density = 0.01 volumetric_fog_density = 0.01
volumetric_fog_albedo = Color(0.6, 0.85, 0.9, 1) volumetric_fog_albedo = Color(0.5, 0.78, 0.92, 1)
volumetric_fog_anisotropy = 0.45 volumetric_fog_anisotropy = 0.45
volumetric_fog_length = 72.0 volumetric_fog_length = 72.0
volumetric_fog_ambient_inject = 0.5 volumetric_fog_ambient_inject = 0.5
@@ -73,11 +73,11 @@ environment = SubResource("EnvironmentUnderwater")
[node name="AmbientDirection" type="DirectionalLight3D" parent="."] [node name="AmbientDirection" type="DirectionalLight3D" parent="."]
rotation_degrees = Vector3(-62, -28, 0) rotation_degrees = Vector3(-62, -28, 0)
light_color = Color(0.56, 0.8, 0.82, 1) light_color = Color(0.5, 0.78, 0.88, 1)
light_energy = 1.35 light_energy = 0.9
light_angular_distance = 3.0 light_angular_distance = 3.0
shadow_enabled = true shadow_enabled = true
shadow_opacity = 0.7 shadow_opacity = 0.45
shadow_blur = 2.0 shadow_blur = 2.0
directional_shadow_max_distance = 160.0 directional_shadow_max_distance = 160.0
directional_shadow_fade_start = 0.75 directional_shadow_fade_start = 0.75
+39 -12
View File
@@ -7,14 +7,23 @@ render_mode depth_draw_opaque;
// The mesh has no tangents: perturbed normals are built in world space and written // The mesh has no tangents: perturbed normals are built in world space and written
// to NORMAL in view space. Detail shading comes from the normal maps, a grain map // to NORMAL in view space. Detail shading comes from the normal maps, a grain map
// used as ambient occlusion in the pits, and albedo mottling. // used as ambient occlusion in the pits, and albedo mottling.
//
// Daylight is attenuated spectrally with depth (Beer-Lambert, per channel): red is
// gone first, blue last, and the whole scene darkens by exp(-k * depth). The scalar
// part scales the sun (light() function, directional only) and the sky ambient (AO);
// the chroma part tints the albedo. Artificial lights such as the submarine's
// projectors are not attenuated, so they stay useful on the drop-off. Everything is
// normalised at reference_depth_m, where the look is the authored palette.
uniform vec3 sand_color : source_color = vec3(0.50, 0.46, 0.34); uniform vec3 sand_color : source_color = vec3(0.56, 0.52, 0.42);
uniform vec3 rock_color : source_color = vec3(0.21, 0.20, 0.18); uniform vec3 rock_color : source_color = vec3(0.22, 0.21, 0.19);
uniform vec3 deep_tint : source_color = vec3(0.04, 0.09, 0.15);
uniform float sand_slope_cosine = 0.9397; // cos(20 deg) uniform float sand_slope_cosine = 0.9397; // cos(20 deg)
uniform float rock_slope_cosine = 0.7660; // cos(40 deg) uniform float rock_slope_cosine = 0.7660; // cos(40 deg)
uniform float depth_tint_start_m = 20.0; // Per-channel absorption of clear tropical water, per metre, scaled for readability.
uniform float depth_tint_end_m = 90.0; uniform vec3 water_absorption_per_m = vec3(0.11, 0.04, 0.032);
uniform float reference_depth_m = 24.0;
// Floor on the daylight factor so the drop-off foot stays readable rather than black.
uniform float minimum_daylight = 0.05;
uniform sampler2D sand_normal_map : hint_normal, repeat_enable, filter_linear_mipmap; uniform sampler2D sand_normal_map : hint_normal, repeat_enable, filter_linear_mipmap;
uniform sampler2D rock_normal_map : hint_normal, repeat_enable, filter_linear_mipmap; uniform sampler2D rock_normal_map : hint_normal, repeat_enable, filter_linear_mipmap;
@@ -31,6 +40,7 @@ uniform vec2 ripple_direction = vec2(0.8, 0.6);
varying vec3 world_position; varying vec3 world_position;
varying vec3 world_normal; varying vec3 world_normal;
varying float daylight;
void vertex() { void vertex() {
world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
@@ -92,20 +102,37 @@ void fragment() {
vec3 shading_normal = normalize(mix(sand_normal, rock_normal, rockness)); vec3 shading_normal = normalize(mix(sand_normal, rock_normal, rockness));
NORMAL = normalize((VIEW_MATRIX * vec4(shading_normal, 0.0)).xyz); NORMAL = normalize((VIEW_MATRIX * vec4(shading_normal, 0.0)).xyz);
// Albedo: mottled rock, lightly grained sand, both tinted with depth. // Albedo: mottled rock, lightly grained sand.
vec3 rock_albedo = rock_color * (1.0 + (grain - 0.5) * 2.0 * grain_albedo_contrast); vec3 rock_albedo = rock_color * (1.0 + (grain - 0.5) * 2.0 * grain_albedo_contrast);
vec3 sand_albedo = sand_color * (1.0 + (grain - 0.5) * 0.3); vec3 sand_albedo = sand_color * (1.0 + (grain - 0.5) * 0.3);
vec3 albedo = mix(sand_albedo, rock_albedo, rockness); vec3 albedo = mix(sand_albedo, rock_albedo, rockness);
float depth_m = -world_position.y;
float tint = smoothstep(depth_tint_start_m, depth_tint_end_m, depth_m);
albedo = mix(albedo, deep_tint, tint * 0.6);
ALBEDO = albedo;
// Detail shading: pits of the grain map and ripple troughs read as occlusion. // Water column: spectral transmittance relative to the reference depth.
float depth_m = -world_position.y;
vec3 transmittance = exp(-water_absorption_per_m * (depth_m - reference_depth_m));
float brightness = dot(transmittance, vec3(0.2126, 0.7152, 0.0722));
vec3 chroma = transmittance / max(brightness, 0.001);
daylight = max(brightness, minimum_daylight);
// Normalise so the authored palette holds at the reference depth once the
// reference transmittance (red already filtered by 24 m of water) is applied.
vec3 reference_chroma = exp(-water_absorption_per_m * reference_depth_m);
reference_chroma /= dot(reference_chroma, vec3(0.2126, 0.7152, 0.0722));
ALBEDO = albedo * chroma * reference_chroma;
// Detail shading: pits of the grain map and ripple troughs read as occlusion;
// the daylight factor dims the sky ambient with depth.
float rock_ao = mix(1.0, 0.45 + 0.55 * grain, grain_ao_strength); float rock_ao = mix(1.0, 0.45 + 0.55 * grain, grain_ao_strength);
float sand_ao = mix(1.0, 0.8 + 0.2 * clamp(sand_tangent.z, 0.0, 1.0), grain_ao_strength * 0.6); float sand_ao = mix(1.0, 0.8 + 0.2 * clamp(sand_tangent.z, 0.0, 1.0), grain_ao_strength * 0.6);
AO = mix(sand_ao, rock_ao, rockness); AO = mix(sand_ao, rock_ao, rockness) * daylight;
AO_LIGHT_AFFECT = 0.35; AO_LIGHT_AFFECT = 0.35;
ROUGHNESS = mix(0.95, 0.78 + 0.12 * grain, rockness); ROUGHNESS = mix(0.95, 0.78 + 0.12 * grain, rockness);
METALLIC = 0.0; METALLIC = 0.0;
} }
// Lambert diffuse; the sun (directional) is dimmed by the water column, other lights
// (submarine projectors) are not. Sand and rock are rough enough to skip specular.
void light() {
float sun_factor = LIGHT_IS_DIRECTIONAL ? daylight : 1.0;
float lambert = clamp(dot(NORMAL, LIGHT), 0.0, 1.0);
DIFFUSE_LIGHT += lambert * ATTENUATION * LIGHT_COLOR * ALBEDO * sun_factor / PI;
}