#version 330 core

in vec2 vUV;
out vec4 FragColor;

uniform vec3 iResolution;
uniform float iTime;
uniform float uAlpha;
uniform sampler2D iChannel0;

float gyroid (vec3 p) { return dot(cos(p), sin(p.yzx)); }

float fbm(vec3 p)
{
    float result = 0.0;
    float a = 0.5;
    for (int i = 0; i < 9; ++i)
    {
        p.z += (result + iTime) * 0.1;
        result += abs(gyroid(p / a) * a);
        a /= 1.5;
    }
    return result;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (2.0 * fragCoord - iResolution.xy) / iResolution.y;
    vec3 ray = normalize(vec3(uv, 0.5));
    vec3 blu = texture(iChannel0, fragCoord / 1024.0).rgb;
    vec3 e = vec3(0.1 * blu.y * vec2(iResolution.x / iResolution.y), 0.0);

    // evaluate T(0.) and T at offset positions
    float T0 = fbm(ray);
    float Tx = fbm(vec3(ray.x + e.x, ray.y, ray.z));
    float Ty = fbm(vec3(ray.x, ray.y + e.y, ray.z));
    vec3 normal = normalize(vec3(T0 - Tx, T0 - Ty, 1.0));
    vec3 color = 0.2 + 1.0 * cos(vec3(1.0, 2.0, 3.0) * 5.5 + normal.y);

    fragColor = vec4(color, 0.5);
}

void main()
{
    vec2 fragCoord = vUV * iResolution.xy;
    vec4 outCol;
    mainImage(outCol, fragCoord);
    outCol.a *= uAlpha;
    FragColor = outCol;
}
