#version 450

layout(location = 0) out vec4 outColor;
layout(location = 0) in vec3 inNormal;
layout(location = 1) in vec3 inColor;

#if 0
void main() {

    vec3 N = normalize(inNormal);

    float f = gl_FragCoord.y/768.0f;    
    vec3 grd = mix(vec3(0.1f,0,0), vec3(1,1,1), f);
    
    outColor = vec4(inColor*grd, 1.0f);
}
#endif

#if 0
//uniform float time;

vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }

float simplexNoise(vec2 v){
    const vec4 C = vec4(0.211324865405187, 0.366025403784439,
            -0.577350269189626, 0.024390243902439);
    vec2 i  = floor(v + dot(v, C.yy) );
    vec2 x0 = v -   i + dot(i, C.xx);
    vec2 i1;
    i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
    vec4 x12 = x0.xyxy + C.xxzz;
    x12.xy -= i1;
    i = mod(i, 289.0);
    vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
    + i.x + vec3(0.0, i1.x, 1.0 ));
    vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
        dot(x12.zw,x12.zw)), 0.0);
    m = m*m ;
    m = m*m ;
    vec3 x = 2.0 * fract(p * C.www) - 1.0;
    vec3 h = abs(x) - 0.5;
    vec3 ox = floor(x + 0.5);
    vec3 a0 = x - ox;
    m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
    vec3 g;
    g.x  = a0.x  * x0.x  + h.x  * x0.y;
    g.yz = a0.yz * x12.xz + h.yz * x12.yw;
    return 130.0 * dot(m, g);
}


void main() {
float time = gl_FragCoord.y/700.0f;
    float speed = 1.5;
    float factor = 1 - (time * speed);
    int noiseScale = 80;

    vec4 color = vec4(0.2, 0.6, 0.4, 1);
    vec4 dissolveColor = vec4(0.3, 0.3, 1, 1);

    float noise = simplexNoise(gl_FragCoord.xy / noiseScale);

    float sn1 = step(noise, factor);
    float sn2 = step(noise, factor + 0.1) - sn1;

    dissolveColor *= sn2 * color.a;
    color.a *= sn1;

    outColor = dissolveColor + color;
}
#endif

const mat2 myt = mat2(.12121212, .13131313, -.13131313, .12121212);
const vec2 mys = vec2(1e4, 1e6);

vec2 rhash(vec2 uv) {
  uv *= myt;
  uv *= mys;
  return fract(fract(uv / mys) * uv);
}

vec3 hash(vec3 p) {
  return fract(
      sin(vec3(dot(p, vec3(1.0, 57.0, 113.0)), dot(p, vec3(57.0, 113.0, 1.0)),
               dot(p, vec3(113.0, 1.0, 57.0)))) *
      43758.5453);
}

vec3 voronoi3d(const in vec3 x) {
  vec3 p = floor(x);
  vec3 f = fract(x);

  float id = 0.0;
  vec2 res = vec2(100.0);
  for (int k = -1; k <= 1; k++) {
    for (int j = -1; j <= 1; j++) {
      for (int i = -1; i <= 1; i++) {
        vec3 b = vec3(float(i), float(j), float(k));
        vec3 r = vec3(b) - f + hash(p + b);
        float d = dot(r, r);

        float cond = max(sign(res.x - d), 0.0);
        float nCond = 1.0 - cond;

        float cond2 = nCond * max(sign(res.y - d), 0.0);
        float nCond2 = 1.0 - cond2;

        id = (dot(p + b, vec3(1.0, 57.0, 113.0)) * cond) + (id * nCond);
        res = vec2(d, res.x) * cond + res * nCond;

        res.y = cond2 * d + nCond2 * res.y;
      }
    }
  }

  return vec3(sqrt(res), abs(id));
}

void main() {

    //vec3 N = normalize(inNormal);
    vec3 N = inNormal * 0.5f;

    float f = gl_FragCoord.y/768.0f;    
    vec3 grd = mix(vec3(0.1f,0,0), vec3(1,1,1), f);

    float voro = voronoi3d(N).y;
    
    if (voro - (1.0f-f) < 0) //0.75f)
//    if (voro - N.y < 0) //0.75f)
    {
        discard;
    }
    
    vec3 col = voro * inColor;

    outColor = vec4(col*grd, 1.0f);
//    outColor = vec4(voronoi3d(N*0.5f+0.5f), 1.0f);
//    outColor = vec4(N*0.5f+0.5f, 1.0f);


    
//    outColor = vec4(inColor*grd, 1.0f);
}

