const SnowShader = {
  uniforms: {
    tDiffuse: { value: null },
    iResolution: { value: null },
    iTime: { value: 0.2 },
    size: { value: 0.05 },
    density: { value: 1.0 },
    snowSpeed: { value: 0.6 },
  },
  vertexShader: `
    varying vec2 vUv;
    void main() {
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    #define PI 3.14159265359
    uniform sampler2D tDiffuse;
    uniform vec2 iResolution;
    uniform float iTime;
    uniform float size;
    uniform float density;
    uniform float snowSpeed;
    varying vec2 vUv;

    float ball(vec2 p){
      float d = distance(vec2(.5), p);
      return smoothstep(size, size - 0.05, d);
    }

    float N11(float n){
      return fract(sin(n * 871.213) * 3134.422);
    }

    float N21(vec2 uv){
      return N11(N11(uv.x) + uv.y);
    }

    float snow(vec2 uv,float t){
      vec2 org_uv = vec2(uv.x, uv.y);
      float z = 10.;
      uv.y += t * 0.5;
      vec2 gv = fract(uv * z);
      vec2 id = floor(uv * z);
      gv.x += (sin(N21(id) * 128. + t) * .4);
      gv.y += (sin(N11(N21(id)) * 128. + t) * .4);
      float dots = ball(gv);
      return dots;
    }

    void main(){
      vec3 col = texture(tDiffuse, vUv).rgb;
      vec2 uv = gl_FragCoord.xy / iResolution.xy;
      uv.x *= iResolution.x / iResolution.y;
      float t = iTime * 0.3 * snowSpeed;
      vec2 gh_uv = uv;
      vec3 colSnow = vec3(0.0);
      float m = 0.0;
      for(float i = 0.; i <= 1.; i += 1. / (10.* density)){
        float z = mix(1., .5 , i);
        vec2 offset = vec2(N11(i), N11(N11(i)));
        m += snow((uv + offset) * z, t) * .1;
      }
      colSnow = vec3(m) * 1.2;
      colSnow += col * 1.0 * mix(0.5, 1., uv.y);
      if(colSnow.x > vec3(m).x * 1.2){
        gl_FragColor = vec4(colSnow,1.0);
      }else{
        gl_FragColor = vec4(colSnow,0.0);
      }
    }
  `,
};
export { SnowShader };
