varying vec2 pos;

uniform vec4 uBackgroundColor;
uniform vec4 uLineColor;
uniform vec2 uSubDivs;
uniform int uLevels;

float CalcHatch2D(vec2 pos, vec2 fw)
{
  vec2 start = log(fw) / log(uSubDivs) + 1.0;
  vec2 scale = vec2(1.0) / pow(uSubDivs, floor(start));
  pos *= scale;
  fw *= scale;

  float alpha = 0.0;
  vec2 fade = (1.0 - fract(start)) / float(uLevels - 1);
  for (int i = 0; i < uLevels; ++i)
  {
    vec2 checkPos = fract(0.5 + pos);
    vec2 pp = vec2(1.0) - min(abs(checkPos - 0.5) / fw, 1.0);
    pp *= fade;
    float p = max(pp.x, pp.y);
//    alpha += p * (1.0 - alpha);
    alpha = max(alpha, p);

    pos /= uSubDivs;
    fw  /= uSubDivs;

    fade = min(fade + 1.0 / float(uLevels - 1), 1.0);
  }
  return alpha;
}

vec4 PixelOver(vec4 a, vec4 b)
{
  // pre-multiply
  a.rgb *= a.a;
  b.rgb *= b.a;

  vec4 c = a + b * (1.0 - a.a);

  // unpre-multiply
  if (abs(c.a) > 0.001)
    c.rgb /= c.a;
  else
    c = vec4(0.0);

  return c;
}
void main(void)
{
  float hatch = CalcHatch2D(pos, fwidth(pos));
  gl_FragColor = PixelOver(vec4(uLineColor.rgb, uLineColor.a * hatch), uBackgroundColor);
  gl_FragColor.rgb *= gl_FragColor.a;
}
