10 clustered_forward as clustering, 14 atmosphere::functions::{calculate_visible_sun_ratio, clamp_to_surface}, 15 atmosphere::bruneton_functions::transmittance_lut_r_mu_to_uv, 16 mesh_view_bindings::{globals, light_probes, lights, view}, 17 view_transformations::position_world_to_clip, 19#import bevy_pbr::mesh_view_bindings as view_bindings 21#import aqua::cascade::{CREST_SSS_RANGE, CREST_SSS_UNCOMPRESSED, DEBUG_MODE_BEAUTY, DEBUG_MODE_BEER_LAMBERT, DEBUG_MODE_FAR_TIER, DEBUG_MODE_FOAM, DEBUG_MODE_LIGHT_RADIANCE, DEBUG_MODE_REFLECTION, DEBUG_MODE_REFLECTION_FRACTION, DEBUG_MODE_REFRACTION_VALIDITY, DEBUG_MODE_SEA_FLOOR, DEBUG_MODE_TRANSMISSION, DEBUG_MODE_UNREFRACTED, DEBUG_MODE_WATER_PATH, DEBUG_MODE_WAVE_HEIGHT, LUMINANCE_EPSILON, LocalLightSample, MIN_NORMAL_Y, SAFE_LENGTH_SQUARED, advected_world, begin_invocation, capillary_resolved_weight, cascade_layout, effective_flow, far_tier_weight, field_params, godot_fresnel, invocation_extinction, invocation_ripple, invocation_river_state, invocation_scatter_scale, lod_count, owning_body, sample_displacement, sample_field_flow, sample_field_level, sample_planar_reflection, set_body_optics, set_effective_flow, set_effective_time, set_fragment_river, set_river_ripple, set_xz_footprint, snap_and_transition, surface} 23#import aqua::waves::displace::{FFT_JONSWAP_SLOPE_VARIANCE, GERSTNER_SLOPE_VARIANCE, WAVE_NORMALS_SLOPE_VARIANCE, capillary_normal_slope, crest_sss, detail_normal_sample, far_displacement, far_normal_cross, sample_fft_normal_cross} 25#import aqua::foam::contract::FOAM_PATTERN_RESOLUTION 26#import aqua::foam::shade::{CREST_FOAM_NORMAL_STRENGTH, CREST_FOAM_SPECULAR_BOOST, INV_PI, CREST_FOAM_SPECULAR_FALLOFF, CREST_FOAM_WHITE_COLOR, foam_bubble_colour, local_foam_light, river_streak_density, sample_foam_density, surface_foam_mask} 28#import aqua::shore::water::{blended_water_depth, caustic_bed_radiance} 29#import bevy_aqua_core::deform::{deform_current} 30#import bevy_aqua_core::material::{BodyLightingState, CameraDepthDebug, CameraDepthPath, FoamState, LocalLightingState, MediumState, NearSurface, PrimaryLightState, SurfaceVertexOutput, TransmissionState} 31#import aqua::light::incident::{GODOT_NORMAL_FADE_RATE, GODOT_NORMAL_MINIMUM_STRENGTH, GODOT_SSS_MODIFIER, GODOT_WATER_ALBEDO, LUMINANCE_WEIGHTS, filtered_primary_light_color, ggx_distribution, local_light_contribution, resolve_primary_light, safe_normalize, sample_diffuse_environment, sample_environment, sample_local_light, smith_masking_shadowing, strongest_incident_directional_light, view_direction} 32#import aqua::optics::{camera_depth_path, deep_water_weight, empty_camera_depth_path, far_field_water, resolve_near_surface, resolve_transmission, sample_water_medium, unresolved_wave_roughness} 35fn vertex(vertex: Vertex) -> SurfaceVertexOutput { 36 let deformation = deform_current(vertex, globals.time); 37 var out: SurfaceVertexOutput; 38 out.world_position = deformation.world_position; 39 out.position = position_world_to_clip(deformation.world_position.xyz); 40 out.world_normal = deformation.world_normal; 41 out.undisplaced_xz = deformation.undisplaced_xz; 42 out.sample_data = vec3( 44 deformation.sample_alpha, 45 deformation.wave_height, 47 out.base_world_position = deformation.base_world_position; 51fn prepare_surface_foam( 52 in: SurfaceVertexOutput, 55 lighting_distance: f32, 57 let foam_distance_fade = exp(-lighting_distance * 0.0075); 58 let visible_foam_density = foam_density * foam_distance_fade; 59 var white_foam_density = visible_foam_density; 61 var shared_depth_path = empty_camera_depth_path(); 62 var has_shared_depth_path = false; 63 if visible_foam_density > 0.0 { 64 shared_depth_path = camera_depth_path(in); 65 has_shared_depth_path = true; 66 let foam_depth = shared_depth_path; 67 let shoreline_fade = select( 69 clamp(foam_depth.path_length / 0.27, 0.0, 1.0), 70 foam_depth.has_background, 72 white_foam_density *= shoreline_fade; 73 white_foam = surface_foam_mask( 74 advected_world(in.undisplaced_xz), 83 let streak = river_streak_density( 84 invocation_river_state(), 90 white_foam_density += streak; 91 white_foam += surface_foam_mask( 92 advected_world(in.undisplaced_xz), 100 visible_foam_density, 104 has_shared_depth_path, 108fn directional_scatter( 109 in: SurfaceVertexOutput, 112 primary: PrimaryLightState, 119 var scatter_colour = medium.deep_body_albedo * medium.diffuse_irradiance; 122 if mode >= DEBUG_MODE_BEAUTY 123 && lights.n_directional_lights > 0u { 124 let light = lights.directional_lights[0u]; 125 let light_direction = safe_normalize( 126 light.direction_to_light, 132 let light_radiance = primary.radiance; 133 let towards_sun = pow( 134 max(dot(light_direction, -to_view), 0.0), 137 let pinch = crest_sss(in.undisplaced_xz, surface_lod, in.sample_data.y); 141 let crest_transmission = clamp( 142 (pinch - CREST_SSS_UNCOMPRESSED) / CREST_SSS_RANGE, 146 let view_vertical = abs(to_view.y); 147 let grazing = max(1.0 - view_vertical * view_vertical, 0.0); 148 let dot_nv = max(dot(near.lighting_normal, to_view), 2e-5); 149 let sss_light_mask = smith_masking_shadowing(surface.sun.y, dot_nv); 150 let sss_near = 0.5 * pow(dot_nv, 2.0); 151 let sss_height = max(0.0, in.sample_data.z + 2.5) 152 * pow(max(dot(light_direction, -to_view), 0.0), 4.0) 154 0.5 - 0.5 * dot(light_direction, near.lighting_normal), 159 scatter_colour += (sss_height + sss_near) 161 / (1.0 + sss_light_mask) 163 * GODOT_WATER_ALBEDO; 164 scatter_colour += (surface.sss.x + surface.sss.y * towards_sun) 165 * surface.sss_tint.rgb 172 * max(light_direction.y, 0.0); 174 return scatter_colour; 178 in: SurfaceVertexOutput, 180 primary: PrimaryLightState, 184 input_body: vec3<f32>, 186) -> BodyLightingState { 187 var body = input_body; 191 var foam_ambient_radiance = vec3(0.0); 192 if mode >= DEBUG_MODE_BEAUTY { 196 foam_ambient_radiance = sample_diffuse_environment(vec3(0.0, 1.0, 0.0)); 197 body += medium.diffuse_irradiance * GODOT_WATER_ALBEDO; 198 if foam.visible_density > 0.0 { 199 body += foam_bubble_colour( 200 in.world_position.xz, 202 u32(round(in.sample_data.x)), 204 foam.visible_density, 207 foam_ambient_radiance, 213 if mode >= DEBUG_MODE_BEAUTY && lights.n_directional_lights > 0u { 214 let light = lights.directional_lights[0u]; 215 let light_direction = safe_normalize( 216 light.direction_to_light, 219 let light_radiance = primary.radiance; 220 let lambertian = 0.5 * max(dot(near.lighting_normal, light_direction), 2e-5); 221 body += lambertian * light_radiance * GODOT_WATER_ALBEDO; 224 let perceptual_roughness = unresolved_wave_roughness( 228 near.lighting_normal_strength, 229 near.filtered_detail_variance, 231 let view_alignment = clamp(dot(near.lighting_normal, to_view), 0.0, 1.0); 232 let fresnel = godot_fresnel(view_alignment); 233 let foam_distance_fade = exp(-near.lighting_distance * 0.0075); 234 let foam_factor = smoothstep( 237 medium.foam_density * 0.75, 238 ) * foam_distance_fade; 239 let foam_roughness = (1.0 - fresnel) * foam_factor; 240 let environment_roughness = clamp( 241 perceptual_roughness + foam_roughness, 245 let has_local_lights = primary.point_start < primary.light_end; 249 var sun_roughness = surface.sun.y; 250 if lights.n_directional_lights > 0u || has_local_lights { 251 let foam_surface_roughness = clamp( 252 surface.sun.y + foam_roughness, 256 sun_roughness = min(sqrt( 257 foam_surface_roughness * foam_surface_roughness 258 + perceptual_roughness * perceptual_roughness, 261 return BodyLightingState( 263 foam_ambient_radiance, 266 environment_roughness, 271fn shade_environment_and_sun( 272 world_position: vec3<f32>, 275 primary: PrimaryLightState, 276 body_lighting: BodyLightingState, 279 let reflection = reflect(-to_view, near.lighting_normal); 280 var reflected_radiance = sample_environment( 282 near.lighting_normal, 283 body_lighting.environment_roughness, 285 let planar = sample_planar_reflection(world_position, surface_level, near.lighting_normal); 286 reflected_radiance = mix(reflected_radiance, planar.color, planar.weight); 290 if lights.n_directional_lights > 0u { 291 let light = lights.directional_lights[0u]; 292 let light_direction = safe_normalize( 293 light.direction_to_light, 296 let light_luminance = max( 297 dot(primary.color, LUMINANCE_WEIGHTS), 300 let light_color = primary.color / light_luminance; 301 let light_strength = clamp(light_luminance / surface.reflection.z, 0.0, 1.0); 302 let halfway = safe_normalize( 303 light_direction + to_view, 304 near.lighting_normal, 306 let dot_nl = max(dot(near.lighting_normal, light_direction), 2e-5); 307 let dot_nv = max(dot(near.lighting_normal, to_view), 2e-5); 308 let light_mask = smith_masking_shadowing(body_lighting.sun_roughness, dot_nv); 309 let view_mask = smith_masking_shadowing(body_lighting.sun_roughness, dot_nl); 310 let distribution = ggx_distribution( 311 clamp(dot(near.lighting_normal, halfway), 0.0, 1.0), 312 body_lighting.sun_roughness, 314 let geometric_attenuation = 1.0 / (1.0 + light_mask + view_mask); 315 let sun_specular = distribution 316 * geometric_attenuation / (4.0 * dot_nv + 0.1); 317 reflected_radiance += sun_specular 323 return reflected_radiance; 326fn shade_local_lights( 327 in: SurfaceVertexOutput, 329 primary: PrimaryLightState, 330 body_lighting: BodyLightingState, 333 reflected_input: vec3<f32>, 335) -> LocalLightingState { 336 let has_local_lights = primary.point_start < primary.light_end; 337 let local_sss_enabled = mode >= DEBUG_MODE_BEAUTY && has_local_lights; 338 var local_crest_transmission = 0.0; 339 if local_sss_enabled { 340 let local_pinch = crest_sss( 342 u32(round(in.sample_data.x)), 345 local_crest_transmission = clamp( 346 (local_pinch - CREST_SSS_UNCOMPRESSED) / CREST_SSS_RANGE, 351 let view_vertical = abs(to_view.y); 352 let local_grazing = max(1.0 - view_vertical * view_vertical, 0.0); 353 let foam_active = foam.visible_density > 0.0; 354 var foam_normal = near.normal; 356 let pixel_z = max(-primary.view_z, 0.0); 357 let foam_delta = 0.25 * pixel_z / FOAM_PATTERN_RESOLUTION; 358 let foam_x = surface_foam_mask( 359 advected_world(in.undisplaced_xz), 360 u32(round(in.sample_data.x)), 363 vec2(foam_delta, 0.0), 365 let foam_z = surface_foam_mask( 366 advected_world(in.undisplaced_xz), 367 u32(round(in.sample_data.x)), 370 vec2(0.0, foam_delta), 372 let foam_gradient = vec2(foam_x - foam.white_mask, foam_z - foam.white_mask); 373 foam_normal = safe_normalize( 374 near.normal + CREST_FOAM_NORMAL_STRENGTH 375 * vec3(-foam_gradient.x, 0.0, -foam_gradient.y), 379 var body = body_lighting.body; 380 var reflected_radiance = reflected_input; 381 var local_foam_radiance = vec3(0.0); 383 var local_index = primary.point_start; 384 local_index < primary.spot_start; 387 let light_id = clustering::get_clusterable_object_id(local_index); 388 let sample = sample_local_light( 391 in.world_position.xyz, 395 let contribution = local_light_contribution( 397 near.lighting_normal, 400 body_lighting.sun_roughness, 402 local_crest_transmission, 405 body += contribution.body; 406 reflected_radiance += contribution.reflection; 408 local_foam_radiance += local_foam_light(sample, foam_normal, to_view); 412 var local_index = primary.spot_start; 413 local_index < primary.light_end; 416 let light_id = clustering::get_clusterable_object_id(local_index); 417 let sample = sample_local_light( 420 in.world_position.xyz, 424 let contribution = local_light_contribution( 426 near.lighting_normal, 429 body_lighting.sun_roughness, 431 local_crest_transmission, 434 body += contribution.body; 435 reflected_radiance += contribution.reflection; 437 local_foam_radiance += local_foam_light(sample, foam_normal, to_view); 440 return LocalLightingState( 449 primary: PrimaryLightState, 450 body_lighting: BodyLightingState, 451 local: LocalLightingState, 454 far_water: vec3<f32>, 460 let reflected_radiance = local.reflected * (1.0 - body_lighting.foam_roughness); 463 let reflection_weight = clamp(body_lighting.fresnel * surface.fresnel.z, 0.0, 1.0); 464 if mode == DEBUG_MODE_REFLECTION_FRACTION { 465 return vec4(vec3(reflection_weight), 1.0); 467 if mode == DEBUG_MODE_REFLECTION { 468 return vec4(reflected_radiance * reflection_weight, 1.0); 470 var water = mix(local.body, reflected_radiance, reflection_weight); 471 if foam.visible_density > 0.0 { 472 let mask = CREST_FOAM_WHITE_COLOR.a * foam.white_mask; 477 var foam_light = CREST_FOAM_WHITE_COLOR.rgb * body_lighting.foam_ambient; 478 if lights.n_directional_lights > 0u { 479 let light = lights.directional_lights[0u]; 480 let light_direction = safe_normalize( 481 light.direction_to_light, 486 let light_radiance = primary.radiance * max(light_direction.y, 0.0); 487 let foam_ndl = max(dot(local.foam_normal, light_direction), 0.0); 488 foam_light += CREST_FOAM_WHITE_COLOR.rgb 489 * INV_PI * surface.foam.z * light_radiance * foam_ndl; 490 let foam_reflection = reflect(-to_view, local.foam_normal); 492 max(dot(foam_reflection, light_direction), 0.0), 493 CREST_FOAM_SPECULAR_FALLOFF, 494 ) * CREST_FOAM_SPECULAR_BOOST * light_radiance; 496 foam_light += local.foam_radiance; 497 water = mix(water, foam_light, mask); 499 return vec4(mix(water, far_water, far_tier), 1.0); 503fn fragment(in: SurfaceVertexOutput) -> @location(0) vec4<f32> { 506 set_xz_footprint(max( 507 length(dpdx(in.world_position.xz)), 508 length(dpdy(in.world_position.xz)), 514 if field_params.info.x > 0.5 { 515 slot = u32(sample_field_level(in.world_position.xz).y + 0.5); 517 let bounded = slot > 0u; 518 if !bounded && field_params.info.y < 0.5 { 521 let params = owning_body(slot); 522 let surface_level = select( 523 cascade_layout.bed_range.z, 524 sample_field_level(in.undisplaced_xz).x, 527 begin_invocation(bounded, params); 528 set_effective_time(globals.time); 531 let distance_to_extent = length( 532 params.extent.xy - view.world_position.xz, 534 if distance_to_extent > surface.far_tier.y { 540 var fragment_river_flow = vec4(0.0, 0.0, 1024.0, 0.0); 542 fragment_river_flow = sample_field_flow(in.world_position.xz); 544 if bounded && params.flags.y > 0.5 && fragment_river_flow.z < 0.0 { 547 set_fragment_river(fragment_river_flow); 548 set_effective_flow(select( 549 surface.advection.xy, 550 fragment_river_flow.xy, 551 bounded && params.flags.y > 0.5, 554 let body_optics = bounded && params.optics_a.w > 0.5; 556 select(surface.fog_density.rgb, params.optics_a.rgb, body_optics), 557 select(1.0, params.optics_b.x, body_optics), 561 if bounded && params.flags.y > 0.5 { 562 let speed = length(fragment_river_flow.xy); 564 let bank_fade = clamp(fragment_river_flow.z / 8.0, 0.0, 1.0); 565 set_river_ripple(bank_fade * clamp(0.8 + 0.75 * speed, 0.8, 2.6)); 567 set_river_ripple(1.0); 569 let mode = u32(round(surface.debug.x)); 570 let surface_lod = u32(round(in.sample_data.x)); 571 let geometric_normal = safe_normalize(in.world_normal, vec3(0.0, 1.0, 0.0)); 572 let to_view = view_direction(in.world_position.xyz); 573 let far_diagnostic = mode == DEBUG_MODE_FAR_TIER; 574 var far_tier = select( 576 far_tier_weight(in.base_world_position), 577 mode == DEBUG_MODE_BEAUTY || far_diagnostic, 580 return vec4(vec3(far_tier), 1.0); 582 var far_water = vec3(0.0); 583 var far_water_depth = 0.0; 587 far_water_depth = blended_water_depth(in.world_position.xz); 588 far_tier *= deep_water_weight(far_water_depth); 591 far_water = far_field_water( 602 return vec4(far_water, 1.0); 606 let near = resolve_near_surface(in, surface_lod, geometric_normal, far_tier, mode); 607 let primary = resolve_primary_light(in, near.normal); 608 let medium = sample_water_medium(in, surface_lod, near.lighting_normal, to_view, mode); 609 if mode == DEBUG_MODE_SEA_FLOOR { 610 let depth = clamp(medium.water_depth / surface.sea_floor.y, 0.0, 1.0); 611 return vec4(1.0 - depth, 0.0, depth, 1.0); 613 if mode == DEBUG_MODE_LIGHT_RADIANCE { 614 if lights.n_directional_lights == 0u { 615 return vec4(0.0, 0.0, 0.0, 1.0); 617 let light_radiance = lights.directional_lights[0u].color.rgb * view.exposure; 618 return vec4(light_radiance / 16.0, 1.0); 620 if mode == DEBUG_MODE_WAVE_HEIGHT { 621 let height = clamp(0.5 + 0.5 * in.world_position.y, 0.0, 1.0); 622 return vec4(vec3(height), 1.0); 624 if mode == DEBUG_MODE_FOAM { 625 return vec4(vec3(medium.foam_density), 1.0); 628 let foam = prepare_surface_foam( 632 near.lighting_distance, 634 let scatter = directional_scatter( 646 let scaled_scatter = scatter * invocation_scatter_scale(); 648 resolve_transmission(in, near.normal, scaled_scatter, medium, foam, primary, mode); 649 if transmission.handled { 650 return transmission.output; 652 let body_lighting = shade_water_body( 662 let reflected = shade_environment_and_sun( 663 in.world_position.xyz, 670 let local = shade_local_lights( 680 return compose_water(