#version 330 core
in vec2 UV;
out vec4 fragColor;
uniform sampler2D iChannel0; // Noise tex
uniform vec2 iResolution;
uniform float iGlobalTime;


float time = iGlobalTime*0.2;
float rotTime = time+smoothstep(-1.0+time,1.0+time,time+cos(time*2.));
float epsilon = 0.001;

mat3 rotX(float a)
{
	return mat3(1.,0.,0.,0.,cos(a),-sin(a),0.,sin(a),cos(a));
}
mat3 rotY(float a)
{
	return mat3(cos(a),0.,sin(a),0.,1.,0.,-sin(a),0.,cos(a));
}
mat3 rotZ(float a)
{
	return mat3(cos(a),-sin(a),0.,sin(a),cos(a),0.,0.,0.,1.);
}

vec3 noise(in vec2 c)
{
	return vec3(fract(sin(dot(c.xy, vec2(12.9898,78.233))) * 43758.5453));
}

float pallo(in vec3 p, float s)
{
	return length(p) - s;
}

float scene(vec3 r)
{
	r -= pallo(r,1.+.5*sin(time));
	r.x = mod(r.x,pallo(r,.5+.2*sin(time*1.4)));
	r.y = mod(r.y,pallo(r,.5+.2*cos(time)));
	r.z = mod(r.z,pallo(r,.5+.2*sin(time*1.9)));
	vec3 b2pos = vec3(r.x + 0.25, r.y-0.35, r.z+0.08);
	vec3 b3pos = vec3(r.x - 0.3, r.y+0.4, r.z-0.5);
	return length(min(min(min(pallo(r,.55),pallo(b2pos,.3)),pallo(r+.25,.25)),pallo(b3pos,.1)));
}

vec3 mars(vec3 c, vec3 p)
{
	float rDist, sDist = 0.;
	vec3 rpos;
	for(int i=0;i<12;++i){
		rpos   = c + rDist*p;
		sDist  = scene(rpos);
		rDist += sDist;
		if(sDist <= epsilon){
			return vec3( rDist );
		}
	}
	return vec3(99.);
}

vec3 paint(vec3 f)
{
	vec3 col=1.-smoothstep(.0,55.,f);
	col.x=.49*smoothstep(.4,.6,col.x);
	col.y=.06*smoothstep(.4,.6,col.y);
	col.z=.59*smoothstep(.4,.6,col.z);
	return .9-col;
}

void main()
{
	// Normalized location
	vec2 p = 1.0 - 2.0*UV;
	// Aspect ratio fix
	p.y *= iResolution.y/iResolution.x;
	// Offset and some movement
	float zOff = -1.5+.2*sin(time*5.);
	// Rotation matrix & projection plane & camera
	mat3 rotation = rotX(2.3*rotTime)*rotY(1.7*rotTime)*rotZ(.9*rotTime);
	vec3 c  = vec3(p, zOff)*rotation;
	vec3 pp = vec3(0.,0.,zOff+3.5)*rotation;
	pp = normalize(pp);
	vec2 aaOff = vec2(1.0/(2.*iResolution.x),1.0/(2.*iResolution.y));
	vec3 f = vec3(0.0);
	vec3 f1 = mars( vec3(c.x-aaOff.x, c.y-aaOff.y, c.z), pp);
	vec3 f2 = mars( vec3(c.x+aaOff.x, c.y-aaOff.y, c.z), pp);
	vec3 f3 = mars( vec3(c.x-aaOff.x, c.y+aaOff.y, c.z), pp);
	vec3 f4 = mars( vec3(c.x+aaOff.x, c.y+aaOff.y, c.z), pp);
    c += .005;
    f1.x = mars( vec3(c.x-aaOff.x, c.y-aaOff.y, c.z), pp).x;
	f2.x = mars( vec3(c.x+aaOff.x, c.y-aaOff.y, c.z), pp).x;
	f3.x = mars( vec3(c.x-aaOff.x, c.y+aaOff.y, c.z), pp).x;
	f4.x = mars( vec3(c.x+aaOff.x, c.y+aaOff.y, c.z), pp).x;
	f1 = paint(f1);
    f2 = paint(f2);
    f3 = paint(f3);
    f4 = paint(f4);
    f = .3*(f1+f2+f3+f4);
	//float flicker = 0.995 + 0.01*smoothstep(0.0, 0.25, sin(2000.01*time));
	float vignette = 1./(1.+.3*dot(p.xy, p.xy));
	//Old vignette: 0.4 + pow( 0.9/(length(p/3.0)+1.0), 2.0);
	fragColor = vec4( 0.04*noise(time*p)+f*vignette, 1.0);
}

