#version 430

layout(binding=0) uniform sampler2D texSurfEdges;
layout(binding=1) uniform sampler2D texSurfPot;
layout(binding=2) uniform sampler2D texSurfNormals;

in vec2 uv;

layout(location = 0) out vec4 frag;
layout(location = 1) out vec4 frag2;

uniform float g_time;


uniform float flip=1.0;

uniform float overlayAlpha=1.0;

uniform float g_bgAmount = 1.0;
uniform float g_lightAmount = 1.0;
uniform float g_waterClip = 0.0;
uniform float g_bumpStrength = 1.0;

uniform float g_posX = 0.0;
uniform float g_posY = 0.0;

uniform float g_overlayScale = 1.0;

uniform float g_windowWidth = 1280.0;
uniform float g_windowHeight = 720.0;


// from Iq: http://www.iquilezles.org/www/articles/texture/texture.htm
vec4 getTexel( sampler2D s, vec2 p ) {
    //return texture2D(s, p);

    highp vec2 texRes = vec2(g_windowWidth, g_windowHeight);
    p = p*texRes+0.5;

    highp vec2 i = floor(p);
    highp vec2 f = p - i;
    f = f*f*f*(f*(f*6.0-15.0)+10.0);
    p = i + f;

    p = (p - 0.5)/texRes;
    return texture2D(s, p);
}

vec3 spreadSpec3(vec3 c, float sp) {
    sp = fract(sp);
    c.r *= smoothstep(1.0, 0.0, (1.0-sp)*1.0);
    c.g *= smoothstep(1.0, 0.0, abs((sp-0.5)*2.0));
    c.b *= smoothstep(1.0, 0.0, sp*1.0);
    return c;
}

vec4 spreadSpec(vec4 c, float sp) {
    sp = fract(sp);
    c.r *= smoothstep(1.0, 0.0, (1.0-sp)*1.0);
    c.g *= smoothstep(1.0, 0.0, abs((sp-0.5)*2.0));
    c.b *= smoothstep(1.0, 0.0, sp*1.0);
    return c;
}

uniform float surfGridRes2D;

// 3D grid size which is the same for width, height & depth
uniform float surfGridDim3D;

// 1.0 scale puts the surfGrid to xyz coords varying from
// -surfGridDim3D*0.5 to surfGridDim3D*0.5
uniform float surfGridScale = 1.0;

// ivec2 ts = textureSize(s, 0);
// return texelFetch(s, ivec2(c.x*ts.x, c.y*ts.y), 0);


// gl_FragCoord.x

vec3 getPos3D(vec2 tp) {
  //  tp = floor(tp);
    float kb = surfGridRes2D/surfGridDim3D; // 10 for example when dim3d is 100 and res2d is 1000
    vec3 pos3D = vec3(0.0);
    vec2 osa = tp/surfGridDim3D;
    vec2 cellXY = fract(osa)*surfGridDim3D;
    vec2 cellZ = floor(osa);
    float indZ = cellZ.x+cellZ.y*kb;
    pos3D = vec3(cellXY, indZ);
    return pos3D;
}

vec2 getPos2D(vec3 pos3D) {
    vec2 res;
  //  pos3D = floor(pos3D);
    float kb = surfGridRes2D/surfGridDim3D; // 10 for example when dim3d is 100 and res2d is 1000
    res.xy = fract(pos3D.xy/(surfGridDim3D))*(surfGridDim3D);
    float osa = floor(pos3D.z)/kb;
    res.x += fract(osa)*(surfGridRes2D);
    res.y += floor(osa)*(surfGridDim3D);
    return res;
}

vec4 texture2D_(sampler2D s, vec2 p) {
    //return texelFetch(s, ivec2(p.x+0.0, p.y+0.0), 0);
    return texture2D(s, p/surfGridRes2D);
}


void main() {
    vec2 uvS = uv;
    vec4 result = vec4(0.0);

    vec2 tp = vec2(gl_FragCoord.xy);
    //    vec3 posCen3D = vec3(surfGridDim3D*0.5);
    vec3 pos3D = getPos3D(tp)+vec3(0.0);

    float d = 1.50;

    vec3 pos3D_0 = pos3D+vec3(0.0, 0.0, 0.0);
    vec3 pos3D_1 = pos3D+vec3(d, 0.0, 0.0);
    vec3 pos3D_2 = pos3D+vec3(0.0, d, 0.0);
    vec3 pos3D_3 = pos3D+vec3(d, d, 0.0);
    vec3 pos3D_4 = pos3D+vec3(0.0, 0.0, d);
    vec3 pos3D_5 = pos3D+vec3(d, 0.0, d);
    vec3 pos3D_6 = pos3D+vec3(0.0, d, d);
    vec3 pos3D_7 = pos3D+vec3(d, d, d);

    vec2 pos_0 = getPos2D(pos3D_0);
    vec2 pos_1 = getPos2D(pos3D_1);
    vec2 pos_2 = getPos2D(pos3D_2);
    vec2 pos_3 = getPos2D(pos3D_3);
    vec2 pos_4 = getPos2D(pos3D_4);
    vec2 pos_5 = getPos2D(pos3D_5);
    vec2 pos_6 = getPos2D(pos3D_6);
    vec2 pos_7 = getPos2D(pos3D_7);

    float surfPos = 0.0;

    float p_0 = texture2D_(texSurfPot, pos_0).r-surfPos;
    float p_1 = texture2D_(texSurfPot, pos_1).r-surfPos;
    float p_2 = texture2D_(texSurfPot, pos_2).r-surfPos;
    float p_3 = texture2D_(texSurfPot, pos_3).r-surfPos;
    float p_4 = texture2D_(texSurfPot, pos_4).r-surfPos;
    float p_5 = texture2D_(texSurfPot, pos_5).r-surfPos;
    float p_6 = texture2D_(texSurfPot, pos_6).r-surfPos;
    float p_7 = texture2D_(texSurfPot, pos_7).r-surfPos;

    // result is the average position of the edge intersections
    int numInters = 0;
    result.rgb = vec3(0.0);

    // grid cube corner indexes are like this
    //     4 --- 5
    //   / |    /|
    //  0 ---- 1 |
    //  |  |   | |
    //  |  6 --| 7
    //  | /    |/
    //  2 ---- 3

    if (//(p_0*p_1 <= 0.0) ||
        (p_0*p_2 < 0.0) ||
        (p_1*p_3 < 0.0) ||
        (p_5*p_7 < 0.0) ||
        (p_4*p_6 < 0.0) ||
        (p_0*p_4 < 0.0) ||
        (p_1*p_5 < 0.0) ||
        (p_2*p_3 < 0.0) ||
      //  (p_2*p_6 <= 0.0) ||
      //  (p_4*p_5 <= 0.0) ||
     //   (p_1*p_5 <= 0.0) ||
      //  (p_3*p_7 <= 0.0) ||
      //  (p_6*p_7 <= 0.0) ||
        false) {
        numInters=1;
    }

    if (numInters>0 && pos3D_6.z < surfGridDim3D) {
        float tot = p_0+p_1+p_2+p_3+p_4+p_5+p_6+p_7;
        vec3 norms = texture2D_(texSurfNormals, pos_0).rgb;
       // float pots = texture2D_(texSurfPot, pos_0).r;
        //   result.rgb = vec3(0.5); // -normalize(norms.rgb)*pots*5.0;
       // result.rgb = -(norms.rgb)*pots*8.0;
      //  result.rgb = -normalize(norms.rgb)*pots;
        result.rgb = -normalize(norms.rgb)*tot;
        result.rgb = (clamp(result.rgb, -1.0, 1.0)+vec3(1.0));
        // result.rgb = vec3(1.0);
    } else {
        result.rgb = vec3(-1000.0);
    }

    result.a = 1.0;

    frag = result;
    frag2 = vec4(0.0, 0.0, 0.0, 0.0);
}
