
const int WAVE_COUNT = 6;

const vec2 WaveDir[WAVE_COUNT] = vec2[](
    vec2( 1.0, 0.2),
    vec2(-0.6, 0.8),
    vec2( 0.7,-0.5),
    vec2(-0.9,-0.3),
    vec2( 0.3, 1.0),
    vec2(-0.7, 0.4)
);

const float WaveSteepness[WAVE_COUNT] = float[](
    0.08,
    0.06,
    0.05,
    0.035,
    0.020,
    0.010
);
const float WaveLength[WAVE_COUNT] = float[](
    20.0,
    14.0,
    9.0,
    6.0,
    4.0,
    2.5
);
const float WaveSpeed[WAVE_COUNT] = float[](
    0.12, 0.18, 0.25, 0.15, 0.3, 0.20
);


vec3 GerstnerWave(
    vec2 pos,
    vec2 dir,
    float steepness,
    float wavelength,
    float speed,
    float time)
{
    dir = normalize(dir);

    float k = 6.2831853 / wavelength;
    float c = speed;

    float f = k * dot(dir, pos) + c * time;

    float a = steepness / k;

    return vec3(
        dir.x * (a * cos(f)),
        a * sin(f),
        dir.y * (a * cos(f))
    );
}


vec3 WaterDisplacement(vec2 p)
{
    vec3 wave = vec3(0.0);

    for(int i = 0; i < WAVE_COUNT; i++)
    {
        wave += GerstnerWave(
            p,
            WaveDir[i],
            WaveSteepness[i],
            WaveLength[i],
            WaveSpeed[i],
            frameTimeCounter
        );
    }

    return wave;
}

vec3 WaterNormal(vec2 p)
{
    const float e = 0.05;

    vec3 p0 = vec3(p.x,0.0,p.y) + WaterDisplacement(p);

    vec3 px = vec3(p.x+e,0.0,p.y) + WaterDisplacement(p+vec2(e,0.0));

    vec3 pz = vec3(p.x,0.0,p.y+e) + WaterDisplacement(p+vec2(0.0,e));

    vec3 dx = px - p0;
    vec3 dz = pz - p0;

    return normalize(cross(dz,dx));
}