#version 450
layout(set = 0, binding = 0) uniform _Time { float Time; };
layout(set = 0, binding = 1) uniform _Offset { vec2 Offset; };
layout(set = 0, binding = 2) uniform _Zoom { float Zoom; };
layout(location = 0) in vec2 fsin_Position;
layout(location = 0) out vec4 fsout_Color;
float beat = 0.9375;
float beats = (Time / beat) - 44. + 8.;


#define PI 3.14159265358979323846
const vec3 purple = vec3(0.298, 0.176, 0.459);
const vec3 yellow = vec3(0.675, 0.635, 0.22);

#define ITS 400.

float hash(vec3 p)
{
    p  = fract( p*0.3183099+.1 );
	p *= 17.0;
    return fract( p.x*p.y*p.z*(p.x+p.y+p.z) );
}

float noise(in vec3 x)
{
    vec3 p = floor(x);
    vec3 f = fract(x);
    f = f*f*(3.0-2.0*f);
	
    return mix(mix(mix( hash(p+vec3(0.,0.,0)), 
                        hash(p+vec3(1.,0.,0)),f.x),
                   mix( hash(p+vec3(0.,1.,0)), 
                        hash(p+vec3(1.,1.,0)),f.x),f.y),
               mix(mix( hash(p+vec3(0.,0.,1)), 
                        hash(p+vec3(1.,0.,1)),f.x),
                   mix( hash(p+vec3(0.,1.,1)), 
                        hash(p+vec3(1.,1.,1)),f.x),f.y),f.z);
}

void pR(inout vec2 p, float a) {
    // thx to hg (http://mercury.sexy/hg_sdf)
	p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
}

vec3 scene(vec3 p)
{
    float n = beats * 2.;
    
    //n = mod(n, 6.); // loop dur
    //n += 20.; // start
    
    float lum = 0.02;
    lum += sin(n / 5.)*0.006; // slow pulse
    
    
    //float pump = max(0.8, (1.-fract(n)));
    
    p *= smoothstep(0., 12., n);
    p *= 5. + sin(n / 3.); // slow zoom in<->out
    
    pR(p.yz, (p.x * 4. + n * 4.) * 0.1); // x axis spiral
    pR(p.xy, (p.z * 2. + n) * 0.3); // spin
    
    pR(p.zx, noise(p * 2. + n) * smoothstep(34., 52., n));
    pR(p.xy, (noise(p * 4. + n) - 0.5) * smoothstep(42., 64., n));
    
    pR(p.yz, n);
    
    
    p.x *= 1. - smoothstep(22., 30., n);
    
    float field = length(p - clamp(p, -0.05, 0.05));
    
    float cube = 1. / field * lum;
    vec3 cubec = min(1., cube) * purple * 0.13;
    
    vec3 c = cubec;
    c *= 300. / ITS;
    c *= smoothstep(0., 3., n);
    return c;
}

void main()
{
	//vec2 iResolution = vec2(80., 45.);
    //vec2 uv = (fsin_Position.xy - (iResolution.xy * 0.5)) / iResolution.yy;
	vec2 uv = fsin_Position;
	
	
    vec3 c = vec3(0.0);
    
    float hr = 0.3;
    for(float z = -hr; z < hr; z += 1. / ITS)
    {
        c += scene(vec3(uv, z));
    }
    c = clamp(c, 0., 1.);
    
    //c -= smoothstep(0.55, 1.3, abs(uv.x)) * 0.05; // vignette x
    //c -= smoothstep(0.17, 0.7, abs(uv.y)) * 0.05; // vignette y
    c += sin(Time * 0.4) * 0.02; // ambience
    //c += noise(vec3(uv * 2000., 0.)) * 0.02; // grain
    //c -= step(0.35, abs(uv.y)); // letterbox
	
	c = (c * smoothstep(0., 0.3, beats - 11.)); // fade in
	
	c = (c * (1. - smoothstep(0., 0.7, beats - 80.))); // fade out
	

	
	c = clamp(c, 0., 1.);
    
	fsout_Color = vec4(c, 1.);
}