 {
   const vec2 wind = foliageIntensFact
     * windStrength
-    * vec2(sin(worldPos.x * 0.05 + time * foliageFreq));
-  const float windS = length(windStrength);
+    * clamp(vec2(smoothTriangleWave(time * foliageFreq)) * 0.4 + 0.6, 0.0, 1.0);
+  const float windS = clamp(length(windStrength), 0.0, 1.0);
 
   applyDetailBending(localPos, worldNormal, worldPos,
     0.0, 0.0, time, intensity, intensity, windS * 5.0, 1.0, 0.1, 

  inout vec3 vPos,
  vec3 vNormal,
  vec3 objectPosition,
  float fDetailPhase,
  float fBranchPhase,
  float fTime,
  float fEdgeAtten,
  float fBranchAtten,
  float fBranchAmp,
  float fSpeed,
  float fDetailFreq,
  float fDetailAmp)
{
  float fObjPhase = dot(objectPosition.xyz, vec3(1.0));  
  fBranchPhase += fObjPhase;
  float fVtxPhase = dot(vPos.xyz, vec3(fDetailPhase + fBranchPhase));  

  vec2 vWavesIn = fTime + vec2(fVtxPhase, fBranchPhase);
  vec4 vWaves = (fract(vWavesIn.xxyy *
             vec4(SIDE_TO_SIDE_FREQ1, SIDE_TO_SIDE_FREQ2, 
                  UP_AND_DOWN_FREQ1, UP_AND_DOWN_FREQ2)) *
             2.0 - 1.0) * fSpeed * fDetailFreq;
  vWaves = smoothTriangleWave(vWaves);
  vec2 vWavesSum = vWaves.xz + vWaves.yw;  

  vPos.xyz += vWavesSum.x * vec3(fEdgeAtten * fDetailAmp * vNormal.xyz);
  vPos.y += vWavesSum.y * fBranchAtten * fBranchAmp;
}

void applyMainBending(inout vec3 pos, vec2 wind, float bendScale)
{
  float length = length(pos);
  float bf = pos.y * bendScale;
  bf += 1.0;
  bf *= bf;

}
// <-

void applyGrassBending(inout vec3 pos, vec2 wind)
{
  const float falloff = clamp(pos.y * pos.y, 0.0, 1.0);
  const float windLength = length(wind);
  const vec3 windDir = vec3(wind.x, -windLength * windLength, wind.y);
  pos.xyz += falloff * windDir;
}

vec2 calcWindStrength(float time)
{
  return clamp(
    vec2(
      noise(vec3(time * windStrengthFreq, 0.0, 0.0)), 
      noise(vec3(0.0, time * windStrengthFreq, 0.0))
    ), 0.0, 1.0) * 2.0 - 1.0;
}

void applyTreeWind(
