version 4
const int nlayers=5;

/*layout(binding = 5)*/ uniform sampler2D spectrum_1_2_Sampler;
/*layout(binding = 6)*/ uniform sampler2D spectrum_3_4_Sampler;

const float FFT_SIZE   = 256.0;
const float GRID1_SIZE = 5488.0f;
const float GRID2_SIZE = 392.0f;
const float GRID3_SIZE = 28.0f;
const float GRID4_SIZE = 2.0f;

const float IGRID1_SIZE = 2.0 * 3.141592657 * FFT_SIZE / GRID1_SIZE;
const float IGRID2_SIZE = 2.0 * 3.141592657 * FFT_SIZE / GRID2_SIZE;
const float IGRID3_SIZE = 2.0 * 3.141592657 * FFT_SIZE / GRID3_SIZE;
const float IGRID4_SIZE = 2.0 * 3.141592657 * FFT_SIZE / GRID4_SIZE;


uniform float t;
in  vec2 uv;
out vec4 fragdata[nlayers];

vec2 getSpectrum(float k, vec2 s0, vec2 s0c)
{
    float w = sqrt(9.81 * k * (1.0 + k * k / (370.0 * 370.0)));
    float c = cos(w * t);
    float s = sin(w * t);
    return vec2((s0.x + s0c.x) * c - (s0.y + s0c.y) * s, (s0.x - s0c.x) * s + (s0.y - s0c.y) * c);
}

vec2 i(vec2 z)
{
 return vec2(-z.y, z.x); // returns i times z (complex number)
}

void main()
{
    vec2 st = floor(uv * FFT_SIZE) / FFT_SIZE;
    float x = uv.x > 0.5 ? st.x - 1.0 : st.x;
    float y = uv.y > 0.5 ? st.y - 1.0 : st.y;

    vec4 s12 = texture(spectrum_1_2_Sampler, uv);
    vec4 s34 = texture(spectrum_3_4_Sampler, uv);
    vec4 s12c = texture(spectrum_1_2_Sampler, vec2(1.0 + 0.5 / FFT_SIZE) - st);
    vec4 s34c = texture(spectrum_3_4_Sampler, vec2(1.0 + 0.5 / FFT_SIZE) - st);

    vec2 k1 = vec2(x, y) * IGRID1_SIZE;
    vec2 k2 = vec2(x, y) * IGRID2_SIZE;
    vec2 k3 = vec2(x, y) * IGRID3_SIZE;
    vec2 k4 = vec2(x, y) * IGRID4_SIZE;

    float K1 = length(k1);
    float K2 = length(k2);
    float K3 = length(k3);
    float K4 = length(k4);

    float IK1 = K1 == 0.0 ? 0.0 : 1.0 / K1;
    float IK2 = K2 == 0.0 ? 0.0 : 1.0 / K2;
    float IK3 = K3 == 0.0 ? 0.0 : 1.0 / K3;
    float IK4 = K4 == 0.0 ? 0.0 : 1.0 / K4;

    vec2 h1 = getSpectrum(K1, s12.xy, s12c.xy);
    vec2 h2 = getSpectrum(K2, s12.zw, s12c.zw);
    vec2 h3 = getSpectrum(K3, s34.xy, s34c.xy);
    vec2 h4 = getSpectrum(K4, s34.zw, s34c.zw);

    fragdata[0] = vec4(h1 + i(h2), h3 + i(h4));
    fragdata[1] = vec4(i(k1.x * h1) - k1.y * h1, i(k2.x * h2) - k2.y * h2);
    fragdata[2] = vec4(i(k3.x * h3) - k3.y * h3, i(k4.x * h4) - k4.y * h4);
    if (nlayers==5)
    {
     fragdata[3] = fragdata[1] * vec4(IK1, IK1, IK2, IK2);
     fragdata[4] = fragdata[2] * vec4(IK3, IK3, IK4, IK4);
    }
}
