From fc8342887adf03c78388e65fbea9d1cf98db28c8 Mon Sep 17 00:00:00 2001
From: Stuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Date: Sat, 9 Apr 2022 16:26:00 +0100
Subject: [PATCH] WS30: Coastline beaches and cliffs

Landclass information is typically not high enough resolution
to render small beaches and coastline features.

This commit uses the steepness of the elevation mesh
to procedurally generate:
a) sea-cliffs (poorly - just a texture at present)
b) beaches, which mix into translucent shallow water
c) breaking waves (poorly - uses the wind direction rather than the
slope normal)
---
 Materials/regions/europe.xml         |  3 +++
 Materials/regions/global-summer.xml  | 10 +++++++++-
 Materials/regions/united_kingdom.xml |  3 +++
 Shaders/ws30-ALS-ultra.frag          | 17 ++++++++++++-----
 Shaders/ws30-water.frag              | 10 +++++++---
 5 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/Materials/regions/europe.xml b/Materials/regions/europe.xml
index 736cac277..e31bc9345 100644
--- a/Materials/regions/europe.xml
+++ b/Materials/regions/europe.xml
@@ -367,6 +367,7 @@
       <texture>Terrain/tidal.png</texture>
       <texture n="10">Terrain/mud.png</texture>
       <texture n="14">Terrain/sand_overlay.png</texture>
+      <texture n="15">Terrain/sand1.png</texture>
       <texture n="20">Terrain/sand6_hires.png</texture>
     </texture-set>
     <parameters>
@@ -380,6 +381,8 @@
       <overlay_alpha>1.21</overlay_alpha>
       <use_grain>0</use_grain>
       <grain_layer_magnification>4.0</grain_layer_magnification>
+      <waterline-start>0.99</waterline-start>
+      <waterline-end>0.995</waterline-end>
     </parameters>
     <xsize>1000</xsize>
     <ysize>1000</ysize>
diff --git a/Materials/regions/global-summer.xml b/Materials/regions/global-summer.xml
index dd704b892..8e5d36435 100644
--- a/Materials/regions/global-summer.xml
+++ b/Materials/regions/global-summer.xml
@@ -418,9 +418,14 @@
   <material include="Materials/base/water.xml">
     <name>Ocean</name>
     <effect>Effects/water</effect>
-    <texture>Terrain/water.png</texture>
+    <texture-set>
+      <texture n="0">Terrain/water.png</texture>
+      <texture n="15">Terrain/sand1.png</texture>
+    </texture-set>
     <parameters>
       <edge-hardness>0.8</edge-hardness>
+      <waterline-start>0.99</waterline-start>
+      <waterline-end>0.995</waterline-end>
     </parameters>
   </material>
 
@@ -565,6 +570,7 @@
       <texture>Terrain/tidal.png</texture>
       <texture n="10">Terrain/mud.png</texture>
       <texture n="14">Terrain/sand_overlay.png</texture>
+      <texture n="15">Terrain/sand1.png</texture>
       <texture n="20">Terrain/sand6_hires.png</texture>
     </texture-set>
     <parameters>
@@ -578,6 +584,8 @@
       <overlay_alpha>1.21</overlay_alpha>
       <use_grain>0</use_grain>
       <grain_layer_magnification>4.0</grain_layer_magnification>
+      <waterline-start>0.99</waterline-start>
+      <waterline-end>0.995</waterline-end>
     </parameters>
     <xsize>1000</xsize>
     <ysize>1000</ysize>
diff --git a/Materials/regions/united_kingdom.xml b/Materials/regions/united_kingdom.xml
index 8433c70d1..03572cb10 100644
--- a/Materials/regions/united_kingdom.xml
+++ b/Materials/regions/united_kingdom.xml
@@ -366,6 +366,7 @@
     <texture-set>
       <texture>Terrain/tidal.png</texture>
       <texture n="10">Terrain/mud.png</texture>
+      <texture n="15">Terrain/sand1.png</texture>
       <texture n="14">Terrain/sand_overlay.png</texture>
       <texture n="20">Terrain/sand6_hires.png</texture>
     </texture-set>
@@ -380,6 +381,8 @@
       <overlay_alpha>1.21</overlay_alpha>
       <use_grain>0</use_grain>
       <grain_layer_magnification>4.0</grain_layer_magnification>
+      <waterline-start>0.99</waterline-start>
+      <waterline-end>0.995</waterline-end>
     </parameters>
     <xsize>1000</xsize>
     <ysize>1000</ysize>
diff --git a/Shaders/ws30-ALS-ultra.frag b/Shaders/ws30-ALS-ultra.frag
index 9ebf488c1..35e6ec53f 100644
--- a/Shaders/ws30-ALS-ultra.frag
+++ b/Shaders/ws30-ALS-ultra.frag
@@ -443,11 +443,18 @@ void main()
 
   if ((water_shader == 1) && (fg_photoScenery == false) && fg_materialParams3[lc].x > 0.5) { 
     // This is a water fragment, so calculate the fragment color procedurally
-    // and mix with some sand colour if near an edge
-    //bool adjacentwater = fg_materialParams3[lc_n.x].x > 0.5;
-    //texel = mix(generateWaterTexel(), texel, adjacentwater ? 0.0 : smoothstep(0.1, 0.2, mfact[0]));
-    //texel = mix(generateWaterTexel(), vec4(0.6,0.6,0.4,1.0), adjacentwater ? 0.0 : smoothstep(0.1, 0.2, mfact[0]));
-    texel = mix(vec4(0.6,0.6,0.4,1.0), generateWaterTexel(), smoothstep(0.98,1.0,steepness));    
+    // and mix with some sand and cliff colour depending on steepness
+    vec4 steep_texel = lookup_ground_texture_array(2, ground_tex_coord, lc, dxdy_gc);  // Uses the same index as the gradient texture, which it is
+    vec4 beach_texel = lookup_ground_texture_array(3, ground_tex_coord, lc, dxdy_gc);  // Use the dot texture, which is overloaded to be the beach texture
+    float waterline_min_steepness = fg_materialParams3[lc].y;
+    float waterline_max_steepness = fg_materialParams3[lc].z;
+
+    // Mix from a rocky texture to beach for steep slopes, which invariably represent the elevation mesh not being perfectly
+    // aligned with the landclass mesh.
+    texel = mix(steep_texel, beach_texel, smoothstep(waterline_max_steepness - 0.1, waterline_max_steepness - 0.03, steepness));
+
+    // Mix from the beach into the water, which produces a pleasing translucent shallow water effect.
+    texel = mix(texel, generateWaterTexel(), smoothstep(waterline_min_steepness,waterline_max_steepness,steepness));    
     fragColor = texel;
     fragColor.rgb += getClusteredLightsContribution(ecPosition.xyz, n, fragColor.rgb);    
   } else {
diff --git a/Shaders/ws30-water.frag b/Shaders/ws30-water.frag
index 38d353634..779fca7e6 100644
--- a/Shaders/ws30-water.frag
+++ b/Shaders/ws30-water.frag
@@ -52,6 +52,10 @@ varying vec4 waterTex2;
 varying vec4 waterTex4;
 varying vec3 specular_light;
 
+//WS3.0 varying
+varying float steepness;
+
+
 /////// functions /////////
 
 float getShadowing();
@@ -343,14 +347,14 @@ vec4 generateWaterTexel()
   if (dist < 10000.0)
   {
     float foamSlope = 0.10 + 0.1 * windScale;
-    float waveSlope = N.g;
+    float waveSlope = N.g + min(50.0*(1.0 - steepness), 0.1);
 
-    if ((windEffect >= 8.0) && (waveSlope >= foamSlope)) {
+    if ((steepness < 0.9999) || (windEffect >= 8.0) && (waveSlope >= foamSlope)) {
       //add foam
       st = vec2(waterTex2 * tscale) * 25.0;
       vec4 foam_texel = texture(textureArray, vec3(st, ATLAS_INDEX_SEA_FOAM) );
 
-      texel = mix(texel, max(texel, texel + foam_texel), smoothstep(0.01, 0.50, N.g));
+      texel = mix(texel, max(texel, texel + foam_texel), smoothstep(0.01, 0.50, waveSlope));
     }
   }