#version 330

in vec2 fragTexCoord;
in vec4 fragColor;

uniform sampler2D texture0;
uniform vec2  iResolution;
uniform float iTime;
uniform float iAlpha;

out vec4 finalColor;

#define T_W   6.0
#define T_H   2.8
#define T_HW  (T_W * 0.5)
#define CAM_Y 1.05
#define SPEED 4.5

#define LIGHT_GAP  6.0
#define PILLAR_GAP 6.0

void main() {
    vec2 ndc = (gl_FragCoord.xy - iResolution * 0.5) / iResolution.y;

    float camZ = iTime * SPEED;
    vec3 rd = normalize(vec3(ndc.x, ndc.y, 0.88));

    float tBest = 1e9;
    int   face  = -1;

    if (rd.y < -0.0001) { float t = -CAM_Y        / rd.y; if (t > 0.0 && t < tBest) { tBest = t; face = 0; } }
    if (rd.y >  0.0001) { float t = (T_H - CAM_Y) / rd.y; if (t > 0.0 && t < tBest) { tBest = t; face = 1; } }
    if (rd.x < -0.0001) { float t = -T_HW         / rd.x; if (t > 0.0 && t < tBest) { tBest = t; face = 2; } }
    if (rd.x >  0.0001) { float t =  T_HW         / rd.x; if (t > 0.0 && t < tBest) { tBest = t; face = 3; } }

    const vec3 FOG_COLOUR = vec3(0.09, 0.09, 0.10);

    if (face < 0) { finalColor = vec4(FOG_COLOUR, iAlpha); return; }

    vec3  hit = vec3(rd.x * tBest, CAM_Y + rd.y * tBest, camZ + rd.z * tBest);
    float wz  = hit.z;

    vec2  uv;
    float amb;
    if      (face == 0) { uv = vec2(hit.x / T_W + 0.5, wz / T_W); amb = 0.38; }
    else if (face == 1) { uv = vec2(hit.x / T_W + 0.5, wz / T_W); amb = 0.40; }
    else                { uv = vec2(hit.y / T_H,        wz / T_W); amb = 0.35; }

    float c = texture(texture0, uv).r;
    vec3  colour = vec3(mix(0.215, 0.36, c));

    float lzLocal    = mod(wz, LIGHT_GAP);
    float toLight    = abs(lzLocal - LIGHT_GAP * 0.5);
    float fixtureZ   = smoothstep(0.06, 0.0, toLight - 0.65);
    float fixtureX   = (face == 1) ? smoothstep(0.10, 0.03, T_HW - abs(hit.x)) : 0.0;
    float ptLight    = exp(-toLight * 0.22) * 1.2;

    float pzLocal    = mod(wz + PILLAR_GAP * 0.5, PILLAR_GAP);
    float pillarMask = smoothstep(0.30, 0.0, abs(pzLocal - PILLAR_GAP * 0.5));
    if (face == 2 || face == 3)
        colour *= mix(1.0, 0.58, pillarMask * 0.85);

    if (face == 0) {
        float edgeDist = abs(abs(hit.x) - T_HW * 0.82);
        colour = mix(colour, vec3(0.55, 0.48, 0.48), smoothstep(0.06, 0.0, edgeDist) * 0.42);
    }

    if (face == 1)
        colour = mix(colour, vec3(0.95, 0.97, 1.0), fixtureZ * fixtureX);

    colour *= amb + ptLight * 0.12;
    colour += vec3(0.90, 0.93, 1.0) * fixtureZ * fixtureX * 1.0;

    float fog = exp(-tBest * tBest * 0.006);
    colour    = mix(FOG_COLOUR, colour, fog);

    finalColor = vec4(colour, iAlpha);
}
