// Drifting mist motes above the sea — GPU-driven points. The `position`
// attribute holds a per-particle random seed; actual position is a pure
// function of (seed, time), wrapped into a box around the camera, so there
// is zero CPU work per frame.

export const MIST_VERT = /* glsl */ `
uniform float uTime;
uniform float uPixelRatio;
varying float vAlpha;
varying float vSpark;

void main() {
  const vec3 BOX = vec3(160.0, 26.0, 160.0);
  vec3 s = position; // seed in [-0.5, 0.5]
  vec3 p;
  p.x = s.x * BOX.x + uTime * (0.6 + (s.y + 0.5) * 1.2);
  p.z = s.z * BOX.z + uTime * (0.4 + (s.x + 0.5) * 0.9);
  p.y = 1.2 + (s.y + 0.5) * BOX.y
      + sin(uTime * (0.20 + (s.z + 0.5) * 0.35) + s.x * 40.0) * 1.6;
  // wrap around camera
  p.xz = mod(p.xz - cameraPosition.xz + BOX.xz * 0.5, BOX.xz) - BOX.xz * 0.5 + cameraPosition.xz;

  vec4 mv = viewMatrix * vec4(p, 1.0);
  float d = -mv.z;
  float size = 1.4 + (s.y + 0.5) * 4.5;
  gl_PointSize = min(size * uPixelRatio * (42.0 / max(d, 1.0)), 13.0 * uPixelRatio);
  gl_Position = projectionMatrix * mv;

  float nearFade = smoothstep(2.0, 9.0, d);
  float farFade = 1.0 - smoothstep(60.0, 140.0, d);
  float tw = 0.55 + 0.45 * sin(uTime * (0.6 + (s.z + 0.5) * 2.2) + s.x * 90.0);
  vAlpha = nearFade * farFade * tw;
  vSpark = step(0.47, s.y); // a few bright fireflies among the mist
}
`;

export const MIST_FRAG = /* glsl */ `
precision mediump float;
uniform vec3 uMistCol;
uniform vec3 uSparkCol;
varying float vAlpha;
varying float vSpark;
void main() {
  vec2 c = gl_PointCoord - 0.5;
  float d2 = dot(c, c);
  float fall = exp(-d2 * 14.0) - exp(-0.25 * 14.0);
  if (fall <= 0.0) discard;
  vec3 col = mix(uMistCol * 0.085, uSparkCol * 0.65, vSpark);
  gl_FragColor = vec4(col * fall * vAlpha, 1.0);
}
`;
