#version 330 core

uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;

out vec4 FragColor;

vec3 checkerboard(vec2 p, float size)
{
    p *= size;
    vec2 f = fract(p.xy) - 0.5;
    float c = f.x * f.y > 0.0 ? 1.0 : 0.0;
    return mix(vec3(0.85, 0.0, 0.0), vec3(1.0), c);
}

vec3 objcolor(vec3 p)
{
    return checkerboard(p.xz, 0.2);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 uv = fragCoord.xy / iResolution.xy - 0.5;
    uv.x *= iResolution.x / iResolution.y;

    vec3 lookat = vec3(0.0, -2.0, -iTime * 16.0);
    vec3 cam = vec3(sin(iTime * 2.0) * 4.0, 0.0, 10.0) + vec3(0.0, 0.0, lookat.z);
    vec3 up = vec3(sin(iTime * 2.0 + 3.14) * 1.5, 1.0, 0.0);

    float camdist = 1.0;
    float camsize = 2.0;
    float maxdist = 50.0;

    vec3 v = cam - lookat;
    vec3 camx = normalize(cross(up, v)) * camsize;
    vec3 camy = normalize(cross(v, camx)) * camsize;

    vec3 campoint = cam - normalize(v) * camdist + camx * uv.x + camy * uv.y;
    vec3 ray = normalize(campoint - cam);

    float s = (-2.0 - campoint.y) / ray.y;
    if(s < 0.0) s = (1.0 - campoint.y) / ray.y;

    vec3 p = campoint + ray * s;

    float fadeout = max(maxdist - s, 0.0) / maxdist;

    vec3 col = objcolor(p);
    col *= fadeout;

    fragColor = vec4(col, 1.0);
}

void main() {
    vec4 col = vec4(0.0);
    mainImage(col, gl_FragCoord.xy);
    col.a *= uAlpha;
    FragColor = col;
}
