From e7ff0ce0ce31002ba9837f837994e653bff11b4f Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sun, 8 Feb 2026 22:14:54 -0800 Subject: [PATCH] Add distance-based water opacity and procedural ocean foam Makes distant water more opaque to hide underwater objects and improve visual quality during flight. Also adds animated foam on wave crests. Distance-based opacity: - Water becomes more opaque from 80-400 units distance - Smoothstep fade adds up to 50% opacity at far distances - Hides underwater M2 models and terrain from aerial view - Max alpha increased from 0.82 to 0.95 for distant water Procedural foam: - Generated on wave peaks (positive WaveOffset values) - Uses noise function for natural foam texture - Animated with time and texture coordinates - Adds white highlights to wave crests for ocean realism This improves taxi flight visuals by making oceans look more solid and realistic from altitude, similar to authentic WoW. --- src/rendering/water_renderer.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/rendering/water_renderer.cpp b/src/rendering/water_renderer.cpp index 730fd694..60762544 100644 --- a/src/rendering/water_renderer.cpp +++ b/src/rendering/water_renderer.cpp @@ -115,9 +115,21 @@ bool WaterRenderer::initialize() { result += skyTint; result = max(result, waterColor.rgb * 0.24); + // Ocean foam on wave crests (procedural) + float wavePeak = smoothstep(0.25, 0.5, WaveOffset); // Peaks have positive offset + float foamNoise = fract(sin(dot(TexCoord * 40.0 + time * 0.5, vec2(12.9898, 78.233))) * 43758.5453); + float foam = wavePeak * foamNoise * 0.65; + result += vec3(foam); // Add white foam to wave crests + // Slight fresnel: more reflective/opaque at grazing angles. float fresnel = pow(1.0 - max(dot(norm, viewDir), 0.0), 3.0); - float alpha = clamp(waterAlpha * alphaScale * (0.68 + fresnel * 0.45), 0.12, 0.82); + + // Distance-based opacity: distant water is more opaque to hide underwater objects + float dist = length(viewPos - FragPos); + float distFade = smoothstep(80.0, 400.0, dist); // Start at 80 units, full opaque at 400 + float distAlpha = mix(0.0, 0.5, distFade); // Add up to 50% opacity at distance + + float alpha = clamp(waterAlpha * alphaScale * (0.68 + fresnel * 0.45) + distAlpha, 0.12, 0.95); FragColor = vec4(result, alpha); } )";