#version 430 core
#define PI 3.1415926538f

//layout(local_size_x = 8, local_size_y = 8) in;
layout(local_size_x = 1) in;

//#define LORENZ
#define CLIFFORD
//#define DREAM

layout(rgba32f) uniform image2D img_output;
uniform sampler2D u_skybox;
uniform sampler2D u_tex1;
uniform sampler2D u_tex2;
uniform sampler2D u_tex3;
uniform sampler2D u_tex4;
uniform sampler2D u_tex5;

struct SceneObject{
    vec4 position;
};

layout(std140, binding=2) uniform shader_data{
    vec4 camera_position; // 4 * 4  16
    vec4 camera_rotation; // 4 * 4  32
    vec2 _PixelOffset;    // 4 * 2  40
    ivec2 screenSize;     // 4 * 2  48
    int iterations;       // 4      52
    float _Seed;          // 4      56
    int objectcount;      // 4      60
    int _sample;          // 4      64
    int _samples;         // 4      68
    float dt;             // 4      72
    vec2 padding;         // 4 * 2  80      
};
layout (std430, binding = 3) coherent buffer object_data{
    SceneObject objects[];
};

float distlimit = 500;
float seed = _Seed;
int samples = _samples;
vec2 _Pixel;

float rand(){
    float result = fract(sin(seed / 100.0f * dot(_Pixel, vec2(12.9898f, 78.233f))) * 43758.5453f);
    seed += 1.0f;
    return result;
}

ivec2 GetPixelCoords(float x, float y){
#ifdef LORENZ
    float div = 30.0f;
#endif
#ifdef CLIFFORD
    float div = 3.0f;
#endif
#ifdef DREAM
    float div = 3.0f;
#endif
    x = x / div;
    y = y / div;

    x += 1;
    y += 1;

    x /= 2.0f;
    y /= 2.0f;
    
    return ivec2(int(x * screenSize.x + 0.5f), int(y * screenSize.y + 0.5f));
}



void main(){
    int id = int(gl_GlobalInvocationID.x);

    float x = objects[id].position.x;
    float y = objects[id].position.y;
    float z = objects[id].position.z;

    ivec2 coords = GetPixelCoords(x, y);

    vec4 pixel = imageLoad(img_output, coords);

    //vec4 color = (vec4(249.0f, 29.0f, 0.0f, 255.0f) / 255.0f);
    //vec4 color = (vec4(249.0f, 29.0f, 0.0f, 255.0f) / 255.0f);
    vec4 color = vec4(0);

    //color = mix(color, pixel, .99999f);
    color = mix(color, pixel, .9999f);
    //color = mix(color, pixel, .2f);

    //imageStore(img_output, coords, pixel + color * .05f);
    //imageStore(img_output, coords, pixel + color * .0001f);
    imageStore(img_output, coords, color);

#ifdef LORENZ
    float s=10.0f;
    float r=28.0f;
    float b=2.667f;

    float x_dot = s*(y - x);
    float y_dot = r*x - y - x*z;
    float z_dot = x*y - b*z;

    objects[id].position.x += x_dot * .001f * dt;
    objects[id].position.y += y_dot * .001f * dt;
    objects[id].position.z += z_dot * .001f * dt;
#endif

#ifdef CLIFFORD
    float a =-1.7f;
    float b = 1.8f;
    float c =-1.9f;
    float d =-0.4f;

    objects[id].position.x = sin(a*y)+c*cos(a*x);
    objects[id].position.y = sin(b*x)+d*cos(b*y);
#endif

#ifdef DREAM
    float a =-2.8276f;
    float b = 1.2813f;
    float c =1.9655f;
    float d =0.597f;

    objects[id].position.x = sin(y*b)+c*sin(x*b);
    objects[id].position.y = sin(x*a)+d*sin(y*a);
#endif
}