#version 120

//varying vec4 t_pos;
varying vec3 p, e;
vec2 square(vec2 a) { return vec2(a.x*a.x-a.y*a.y, 2*a.x*a.y); }
vec2 mul(vec2 a, vec2 b) { return vec2(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x); }

vec4 mul(vec4 a, vec4 b) {
	return vec4(
		dot(a, vec4(b.w, b.z, -b.y, b.x)),
		dot(a, vec4(-b.z, b.w, b.x, b.y)),
		dot(a, vec4(b.y, -b.x, b.w, b.z)),
		dot(a, vec4(-b.x, -b.y, -b.z, b.w)));
}
vec4 square(vec4 a) {
	return vec4(a.xyz*2*a.w, a.w*a.w-dot(a.xyz, a.xyz));
}

float mdist(vec2 z, vec2 c) {
	vec2 zd = vec2(0.);
	for (int i = 0; i<100; i++) {
		zd = 2*mul(z, zd)+vec2(1.,0.);
		z = square(z)+c;
		if (length(z)>100) return 2*log(length(z))*length(z)/length(zd);
	}
}
float jdist(vec2 z, vec2 c) {
	float zdl = 1.;
	for (int i = 0; i<100; i++) {
		float zl = length(z);
		if (zl>100) return 2*log(zl)*zl/zdl;
		zdl *= 2*zl;
		z = square(z)+c;
	}
	return 0;
}

float mdist(vec4 z, vec4 c) {
	vec4 zd = vec4(0.);
	for (int i = 0; i<100; i++) {
		zd = 2*mul(z, zd)+vec4(0.,0.,0.,1.);
		z = square(z)+c;
		if (length(z)>100) return 2*log(length(z))*length(z)/length(zd);
	}
}
float jdist(vec4 z, vec4 c) {
	float zdl = 1.;
	for (int i = 0; i<30; i++) {
		float zl = sqrt(dot(z,z)+.1);//length(z);
		if (zl>100) return 2*log(zl)*zl/zdl;
		zdl *= 2*zl;
		z = square(z)+c;
	}
	return 0;
}
uniform vec4 c0;
float D(vec3 p) { return jdist(vec4(p.z,0.,p.xy), c0); }
float intersect(vec3 p0, vec3 d, float t0, int maxiter) {
	vec3 p = p0;
	float t = t0;
	for (int i = 0; i<maxiter && t<20.; i++) {
		float dist = D(p0+d*t)*.25;
		t += dist;
		if (dist<0.01) return t;
	}
	return 1./0.;
}

uniform sampler2D texture;

void main(void) {
	vec3 p0 = e;
	vec3 d = normalize(p-e);
/*	vec3 p0 = vec3(0.,0.,-1.5);
	vec3 d = normalize(vec3(p.xy,3.));*/
	float t = intersect(p0, d, 0, 50);
	if (t<100.) {
		vec3 p1 = p0+t*d;
		float v = D(p1);
		vec3 n = normalize(vec3(D(p1+vec3(.001,.0,.0))-v, D(p1+vec3(.0,.001,.0))-v, D(p1+vec3(.0,.0,.001))-v));
//		gl_FragColor = vec4(max(n.z,0.)+.2);

		vec2 tc = vec2(-n.x, n.z);
		vec4 col = texture2D(texture, tc);
//		vec4 col = vec4(1.0);

		gl_FragColor = col*vec4(0.25+0.75*n.z);
	} else  gl_FragColor = vec4(0.0,0.0,0.0,1.);
}

