   return x * x * (3.0 - 2.0 * x);  
 }
 
+float smoothCurve(float x)
+{  
+  return x * x * (3.0 - 2.0 * x);  
+}
+
 vec4 triangleWave(vec4 x) 
+{  
+  return abs(fract(x + 0.5) * 2.0 - 1.0);  
+}
+
+float triangleWave(float x) 
 {  
   return abs(fract(x + 0.5) * 2.0 - 1.0);  
 }

vec4 smoothTriangleWave(vec4 x) 
{  
  return smoothCurve(triangleWave(x));  
}  

#define SIDE_TO_SIDE_FREQ1 1.975
#define SIDE_TO_SIDE_FREQ2 0.793

  float time,
  vec2 windStrength)
{
  const vec2 detailStrength = clamp(
      vec2(
        noise(vec3(worldPos.x * 2.0 + time * grassFreq, 0.0, 0.0)) * 0.5 + 0.5,
        noise(vec3(worldPos.z * 2.0 + time * grassFreq, 0.0, 0.0)) * 0.5 + 0.5
      )
      , vec2(0.0), vec2(1.0));
  const vec2 mainStrength = clamp(
    vec2(
        (smoothTriangleWave(worldPos.x * 0.05 + time * grassFreq * 0.25) * 0.5 + 0.5) * 0.8 + 0.2,
        (smoothTriangleWave(worldPos.z * 0.05 + time * grassFreq * 0.25) * 0.5 + 0.5) * 0.8 + 0.2
      )
      , vec2(0.0), vec2(1.0));

  const vec2 wind = grassIntensFact
    * windStrength
    * ((mainStrength + detailStrength) * 0.5);

  applyGrassBending(localPos, wind);
} 
