#version 300 es precision highp float; uniform float aspect; in vec2 position; out vec2 screen; void main(void) { screen = position * vec2(aspect, 1.0); gl_Position = vec4(position, 0.0, 1.0); }
#version 300 es precision highp float; uniform float time; in vec2 screen; out vec4 frag_color; vec3 repeat(vec3 v, vec3 v0, vec3 radius) { return mod(v - v0 - radius / 2.0, radius) - radius / 2.0 + v0; } float F(vec3 r) { vec3 r0 = vec3(1.5, 1.5, -mod(time, 3.0)); r = repeat(r, r0, vec3(3.0)); float R = 1.0; return distance(r, r0) - R; } vec3 dF(vec3 r) { float eps = 0.0001; float f = F(r); return normalize(vec3 ( F(r + vec3(eps, 0.0, 0.0)) - f, F(r + vec3(0.0, eps, 0.0)) - f, F(r + vec3(0.0, 0.0, eps)) - f )); } float trace(vec3 p, vec3 a) { float eps = 0.001; float t = 0.0; /* If intersection wasn't found after 256 iterations then it is considered that there is no intersection */ for(int n = 0; n < 256; ++n) { float dist = F(p + a * t); if(dist < 0.0) // Is point beyond the surface? { return -1.0; } else if(dist < eps) // Is point considered as intersection? { return t; } else { t += dist; } } return -1.0; } float attenuation(float dist) { return dist * dist / 16.0 + 1.0; } vec3 diffuse(vec3 point, vec3 light, vec3 normal) { vec3 color = vec3(0.567, 1.0, 0.0); return color * dot(normalize(light - point), normal) / attenuation(distance(light, point)); } float specular(vec3 point, vec3 light, vec3 eye, vec3 normal) { vec3 halfway = normalize(normalize(light - point) + normalize(eye - point)); return pow(dot(halfway, normal), 32.0) / 2.0; } void main(void) { vec3 p = vec3(0.0, 0.0, -1.0); vec3 a = normalize(vec3(screen, 1.0)); vec3 rgb = vec3(0.0); float t = trace(p, a); if(t >= 0.0) // Intersection is found if t >= 0.0 { vec3 r = p + a * t; // Intersection point vec3 n = dF(r); // Surface normal vector at the interserction point vec3 light = vec3(-1.0, 1.0, 0.0); // Light position rgb = diffuse(r, light, n) + specular(r, light, p, n); } frag_color = vec4(rgb, 1.0); }