#extension GL_ARB_gpu_shader5 : enable
#include "/lib/projections.glsl"
#include "/lib/taa/res_params.glsl"
#include "/lib/uniforms.glsl"

uniform float frameTimeCounter;

varying vec2 texcoord;

// Hashing Function, returns vector
vec2 HashVec(vec2 d)
{
    float a = dot(d, vec2(123.4, 234.5));
    float b = dot(d, vec2(234.5, 345.6));
    return sin(58322.51 * sin(vec2(a, b)) + frameTimeCounter * 2.4);
}

vec2 wrapCoordinates(vec2 coords, float size)
{
    return mod(coords, size); // Ensure coordinates fall within the grid
}

// Generates 1 Octave of Perlin Noise
float Octave(vec2 uv, float GridSize)
{
    vec2 GridUv = fract(uv * GridSize);
    vec2 CellId = floor(uv * GridSize);
    vec2 SmoothUv = smoothstep(0.0, 1.0, GridUv);

    float n00 = dot(HashVec(wrapCoordinates(CellId, GridSize)), GridUv);
    float n10 = dot(HashVec(wrapCoordinates(CellId + vec2(1.0, 0.0), GridSize)), GridUv - vec2(1.0, 0.0));
    float n01 = dot(HashVec(wrapCoordinates(CellId + vec2(0.0, 1.0), GridSize)), GridUv - vec2(0.0, 1.0));
    float n11 = dot(HashVec(wrapCoordinates(CellId + vec2(1.0, 1.0), GridSize)), GridUv - vec2(1.0, 1.0));

    float nx0 = mix(n00, n10, SmoothUv.x);
    float nx1 = mix(n01, n11, SmoothUv.x);
    return mix(nx0, nx1, SmoothUv.y);
}

float WaterMap(vec2 pos)
{
    float gradient = 0.0;
    float frequency = 8.0;
    float amplitude = 2.0;

    for (float i = 3; i <= 16; i += 3)
    {
        gradient += (Octave(pos, frequency) + 0.5) / amplitude;
        frequency *= 2.0;
        amplitude *= 2.0;
    }

    return gradient;
}


void main()
{
    /* DRAWBUFFERS:7*/
#ifdef HQ_WATER
#endif
    gl_FragData[0].r = WaterMap(texcoord * 2.0);
}
