

// Uniform variables for texturing
uniform sampler2D 	aaa_tex2d[4];

// Size of Texture for each texture unit
uniform vec2		aaa_tex_size[];

// 0 = time
// 1 = mouse X
// 2 = mouse Y
// 3 = samples (from 2.0 to 16.0)
uniform float		aaa_fu_float[8];

// 0 = iterations
uniform int			aaa_fu_int[4];


// balance between texture and effect
uniform float		aaa_fu_src;
uniform float		aaa_fu_out;


// Colors factors
// 0 = src colors
// 1 = out color
uniform vec4		aaa_fu_vec4[8];


vec3 hsv(in float h, in float s, in float v)
{
	return mix(vec3(1.0), clamp((abs(fract(h + vec3(3, 2, 1) / 3.0) * 6.0 - 3.0) - 1.0), 0.0 , 1.0), s) * v;
}


vec3 formula(in vec2 p, in vec2 c)
{
	const float n = 2.0;
	const int iters = 12;

	float time = aaa_fu_float[0]*0.1;
	vec3 col = vec3(0);
	float t = 1.0;
	float dpp = dot(p, p);
	float lp = sqrt(dpp);
	float r = smoothstep(0.0, 0.2, lp);

	for (int i = 0; i < iters; i++)
	{
		// The transformation
		p = abs(mod(p/dpp + c, n) - n/2.0);

		dpp = dot(p, p);
		lp = sqrt(dpp);

		//Shade the lines of symmetry black
		// Variable width lines
		t *= smoothstep(0.0, 0.01, abs(n/2.0-p.x)*lp)
		   * smoothstep(0.0, 0.01, abs(n/2.0-p.y)*lp)
		   * smoothstep(0.0, 0.01, abs(p.x)*2.0)
		   * smoothstep(0.0, 0.01, abs(p.y)*2.0);

		// Fade out the high density areas, they just look like noise
		r *= smoothstep(0.0, 0.2, lp);

		// Add to colour using hsv
		col += hsv(1.0 - max(p.x, p.y) + t*2.0 + time, 2.0-lp+t, r);

	}

	return (-cos(col/4.0)*0.5 + 0.5)*(t);
}

void main()
{
	vec2 p = gl_TexCoord[0].st-0.5;
	p *= 2.0;
	const vec2 e = vec2(0.06545465634, -0.05346356485);
	vec2 c = aaa_fu_float[0]*e;

	float d = 1.0;
	vec3 col = vec3(0.0);

	float sbs = sqrt(aaa_fu_float[3]);
	float mbluramount = 1.0/aaa_tex_size[0].x/length(e)/aaa_fu_float[3]*2.0;
	float aabluramount = 1.0/aaa_tex_size[0].x/sbs*4.0;
	for (float b = 0.0; b < aaa_fu_float[3]; b++)
	{
		col += formula(
			p + vec2(mod(b, sbs)*aabluramount, b/sbs*aabluramount),
			c + e*mbluramount*b);
	}
	col /= aaa_fu_float[3];

	vec4 src = (texture2D(aaa_tex2d[0], gl_TexCoord[0].st) * aaa_fu_src) * aaa_fu_vec4[0];
	vec4 fx  = (vec4(col, 1.0) * aaa_fu_out) * aaa_fu_vec4[1];

	gl_FragColor = vec4( (src + fx) );
}
