#ifdef GL_ES
precision mediump float;
#endif
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform sampler2D backbuffer;
#define ITE_MAX 100
#define DIST_COEFF 1.00
#define DIST_MIN 0.01
#define DIST_MAX 2000.0
#define pi 3.14159265
float perlin(vec3 p) {
vec3 i = floor(p);
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
vec3 f = cos((p-i)*pi)*(-.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 map_flat(vec3 p) {
float t = DIST_MAX;
float w = 0.0;
w = 0.1 + dot(p, vec3(0.0, 1.0, 0.0));
t = min(t, w);
return t;
}
float map(vec3 p0) {
vec3 p = p0;
float t = DIST_MAX;
float w = 0.0;
float tt = mod(0.95 * time, 1.8) - 0.9;
w = 0.6 * length(p + vec3(-0.4, -0.0 ,0.0) + 0.9 * sin(tt)) - 0.2 + 0.6 * sin(-tt - 1.2) * 0.3 * perlin(p * (tt - 0.81) * 60.0);
t = min(t, w);
return t;
}
float lambert(vec3 p) {
vec3 light = normalize(vec3(0.0, 1.0,0.0));
vec3 eye = normalize(vec3(0.0, 0.0, 1.0));
vec3 pos = normalize(p);
vec3 hv = normalize(light+ eye);
float d = max(dot(pos,-hv), 0.0);
return d;
}
float getDistance(float t, vec3 dir, vec3 eye){
for(int i = 0 ; i < ITE_MAX; i++) {
float ttemp = map(t * dir + eye);
ttemp *= map_flat(t * dir + eye);
if (ttemp < DIST_MIN)
break;
t += ttemp * DIST_COEFF;
}
return t;
}
void main( void ) {
vec2 uv = ( gl_FragCoord.xy / resolution.xy ) * 2.0 - 1.0;
float aspect = resolution.x / resolution.y;
vec3 dir = normalize(vec3(uv * vec2(aspect, 1.0), 1.0));
vec3 eye = vec3(mouse.x, mouse.y, -1.0);
float t = 0.0;
t = getDistance(t, dir, eye);
vec3 ip = eye + dir * t;
vec3 color = vec3(1.0,1.0,1.0);
if (t < 1.8){
color = vec3(t *0.3,t*0.3,t);
}
color = color * lambert(ip) ;
//vec3 bg = vec3(uv.y * uv.y, 0.4,0.0);
gl_FragColor = vec4(color, 1.0)+ 0.65* texture2D(backbuffer, gl_FragCoord.xy / resolution.xy);
}