varying highp vec2 vTextureCoord;
uniform float anger;
uniform float alpha;
uniform float offset;

// Noise function y to Las^Mercury
float noise(vec3 p) 
{
	vec3 i = floor(p);
	vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
	vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
	a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
	a.xy = mix(a.xz, a.yw, f.y);
	return mix(a.x, a.y, f.z);
}

float sphere(vec3 p, vec4 spr)
{
	return length(spr.xyz - p) - spr.w;
}

float eye(vec3 p)
{
	float d = sphere(p * vec3(.2, .4, 1.), vec4(.0, -1., .0, 1.));
	p += offset;
	return d + anger * (noise(p+vec3(.0, iTime*2., .0)) + noise(p * 3.) * .5) *.25 * p.y ;
}

float scene(vec3 p)
{
	return min(100. - length(p), abs(eye(p)));
}

vec4 raymarch(vec3 org, vec3 dir)
{
	float d = 0.0, c = 0.0, eps = 0.02;
	vec3 p = org;
	bool hit = false;
	
	for(int i = 0; i < 64; i++)
	{
		d = scene(p) + eps;
		p += d * dir;
		if( d>eps )
		{
			if(eye(p) < .0)
				hit = true;
			if(hit)
       			c = float(i)/64.;
		}
	}
	return vec4(p,c);
}

void mainImage( out vec4 fragColor)
{
    vec2 uv = vec2(vTextureCoord.x, 1. - vTextureCoord.y);
    vec2 v = -1.0 + 2. * uv.xy;
	v.x *= iResolution.x/iResolution.y;
	
	vec3 org = vec3(0., -3., 6.);
	vec3 dir = normalize(vec3(v.x, -v.y, -1));
	
	vec4 p = raymarch(org, dir);
	float glow = p.w;
	
    vec4 col = mix(vec4(1.,1.,.3,alpha), vec4(.8,.1,.1,alpha), p.y * 0.05 + .5);
	
	fragColor = mix(vec4(0.), col, pow(glow * 1.5, 2.));
}

