#version 330

in vec2 fragTexCoord;
in vec4 fragColor;

uniform sampler2D texture0;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform vec4      colDiffuse;

uniform vec2  iResolution;
uniform float iTime;
uniform float iAlpha;
uniform float iOffsetY;

out vec4 finalColor;

// ShaderToy porting note:
//   gl_FragCoord.xy / iResolution  ==  fragCoord / iResolution.xy
//   Y=0 is at the bottom in both.

float hash(vec2 p) {
    p = fract(p * vec2(127.1, 311.7));
    p += dot(p, p + 19.19);
    return fract(p.x * p.y);
}

float noise(vec2 p) {
    vec2 i = floor(p);
    vec2 f = fract(p);
    vec2 u = f * f * (3.0 - 2.0 * f);
    return mix(
        mix(hash(i),               hash(i + vec2(1.0, 0.0)), u.x),
        mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x),
        u.y
    );
}

float fbm(vec2 p) {
    float v = 0.0;
    float a = 0.5;
    for (int i = 0; i < 6; i++) {
        v += a * noise(p);
        p  = p * 2.1 + vec2(1.7, 9.2);
        a *= 0.5;
    }
    return v;
}

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution;
    uv.y += iOffsetY;

    float angle = (uv.x - 0.5) * 3.14159 * 0.9;
    float wallX = sin(angle) * 0.5 + 0.5;

    vec2 p = vec2(wallX, uv.y) * 2.5 + iTime * 0.04;

    // Domain warping
    vec2 q = vec2(fbm(p), fbm(p + vec2(3.7, 1.4)));
    float f = fbm(p + 1.5 * q);

    float cloud = smoothstep(0.35, 0.75, f);

    vec3 dark      = vec3(0.10, 0.04, 0.04);
    vec3 cloud_col = vec3(0.65, 0.10, 0.10);
    vec3 color     = mix(dark, cloud_col, cloud);

    // float shadow = sin(uv.x * 3.14159);
    // color *= 0.10 + 0.90 * shadow * shadow * shadow;

    finalColor = vec4(color, 0.5 * iAlpha);
}
