
/*
MS=maxsteps
ST=step
TH=threshold
s=stepcount
t=time
fq=frequency
p1-p3=parametrit
b=brightness
zp=zposition
w=white
k=kaavan arvo
n=normaali
tx=texturemappi
d=diffuse
nd=negatiivinen diffuse (vastavalo)
hl=highlight
*/

varying vec3 p, e;
const float MS  =  180.0;
const float ST  =  0.0075*0.75, TH  =  6.0;

uniform float t,fq,p1,p2,p3,b,zp,w;
uniform vec3 lp;
uniform vec3 posAdd;

uniform float ripple;

float K(in vec3 p) {
	float ball = (sin(p.x*10.0) + p2*sin(p.x*160.0) + p3*sin(t+(p.y+p.z)*80.0)) *
	             (sin(p.y*10.0) + p2*sin(p.y*160.0) + p3*sin(t+(p.x+p.z)*80.0)) *
	             (sin(p.z*10.0) + p2*sin(p.z*160.0) + p3*sin(t+(p.x+p.y)*80.0));
	return ball*p1*4.0+4.0;
}

vec3 N(in vec3 p, in float val) {
	return normalize(vec3(val-K(vec3(p.x+0.01,p.y,p.z)),val-K(vec3(p.x,p.y+0.01,p.z)),val-K(vec3(p.x,p.y,p.z+0.01))));
}

void main(void) {
	vec3 pos = vec3(0.0);
	vec3 dir = normalize(p-e)*ST;
	float k = 0.0, tx, s = 16.0;
	vec3 n,hl,d,nd;

	for (; s < MS; ) {
		pos = posAdd + e+dir*s;
		k = K(pos);
		if (k > TH) break;
		s = s+clamp((TH-k)*5.0,1.0,15.0);
	}

	if (s < MS)
		for (int i = 0; i<9; i++){
			dir = dir*0.5;
			if (k > TH) pos = pos-dir;
			else pos = pos+dir;
			k = K(pos);
		}

	vec3 color = vec3(1.0, 1.0, 1.0);
	vec3 hlColor = vec3(1.0, 1.0, 1.0);
	vec3 fog = vec3(0.0, 0.0, 0.0);

	lp = normalize(dir*lp);

	dir = p-e;
	n = N(pos,k);
	hl = vec3(clamp(dot(reflect(normalize(dir), n), lp), 0.0, 1.0));
	hl = hl*hl*hl*hl*hl*hl*hl*hl*color;
/*	tx = sin(pos.z*4.3+n.z*4.0+t*37.3-sin(pos.x*23.4+n.x*4.0-t*21.4))*
		 sin(pos.x*5.2+n.x*4.0-t*28.1+sin(pos.z*21.4+n.z*4.0-t*17.2))*0.5+0.5;
	tx = tx*tx*tx*p3;*/
	nd = clamp(dot(n,-lp),0.0,1.0)*vec3(vec3(1.0)-hlColor);
	d = clamp(dot(n,lp), 0.0, 1.0)*color/**tx*/+nd*nd;

	gl_FragColor = vec4(lerp(hl+d, fog, clamp(1.0-(MS-s)/MS,0.0,1.0))*b+vec3(w), 1.0);
}

