#ifdef GL_ES precision mediump float; #endif uniform float time; uniform sampler2D backbuffer; uniform vec2 resolution; #define iGlobalTime time #define iResolution resolution const float PI = 3.14159265359; const float NEAR = 1e-1; const float FAR = 1e+3; const float MAX_TIME = 3.0; vec3 hsv2rgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } float random(in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123); } float easeOut(float x) { float a = x - 1.0; return 1.0 - (a * a); } vec4 opU(vec4 d1, vec4 d2) { return (d1.x < d2.x) ? d1 : d2; } float pow2(float x) { return x * x; } mat3 rotX(float angle) { float c = cos(angle); float s = sin(angle); return mat3(vec3(1, 0, 0), vec3(0, c, s), vec3(0.0, -s, c)); } mat3 rotY(float angle) { float c = cos(angle); float s = sin(angle); return mat3(vec3(c, 0, -s), vec3(0, 1, 0), vec3(s, 0, c)); } mat3 rotZ(float angle) { float c = cos(angle); float s = sin(angle); return mat3(vec3(c, s, 0), vec3(-s, c, 0), vec3(0, 0, 1)); } float sdBox(vec3 p, vec3 b) { vec3 d = abs(p) - b; return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0)); } void boxFuta(inout vec4 result, vec3 pos, float value, float sz, float mID) { result = opU(result, vec4(sdBox(rotX(value) * (pos - vec3(.0, sz, -sz)) - vec3(0.0, 0.0, sz), vec3(sz, sz * 0.001, sz)), mID, 0.0, 0.0)); } void box(inout vec4 result, vec3 pos, float sz, float val, float mID) { boxFuta(result, pos, val, sz, mID); result = opU(result, vec4(sdBox(pos - vec3(.0, -sz + sz * 0.001, .0), vec3(sz, sz * 0.001, sz)), mID + 3.0, 0.0, 0.0)); result = opU(result, vec4(sdBox(pos - vec3(.0, .0, sz - sz * 0.001), vec3(sz, sz, sz * 0.001)), mID, 0.0, 0.0)); result = opU(result, vec4(sdBox(pos - vec3(.0, .0, -sz + sz * 0.001), vec3(sz, sz, sz * 0.001)), mID, 0.0, 0.0)); result = opU(result, vec4(sdBox(pos - vec3(-sz + sz * 0.001, .0, .0), vec3(sz * 0.001, sz, sz)), mID, 0.0, 0.0)); result = opU(result, vec4(sdBox(pos - vec3(sz - sz * 0.001, .0, .0), vec3(sz * 0.001, sz, sz)), mID, 0.0, 0.0)); } vec4 map(vec3 pos) { float t = mod(iGlobalTime, MAX_TIME); vec4 dest = vec4(FAR, -1.0, 0.0, 0.0); float u = t / MAX_TIME; float s = easeOut(u); s = smoothstep(0.5, 0.9, u); float r = 2.0 * PI * u; vec3 pBox = rotX(-PI * 0.5) * (pos - ((1.0 - u) * vec3(0.0, 0.0, -49.0) + u * vec3(0.0, 0.0, 49.0))); box(dest, pBox, 500.0, PI * 0.5, 0.0); box(dest, rotZ(r) * rotY(r) * pBox, 5.0, PI * 0.5 * s, 1.0); box(dest, rotY(r) * rotX(r) * pBox, 0.05, 0.0, 2.0); return dest; } vec3 getNormal(in vec3 p) { const float e = 1e-4; return normalize( vec3(map(vec3(p.x + e, p.y, p.z)).x - map(vec3(p.x - e, p.y, p.z)).x, map(vec3(p.x, p.y + e, p.z)).x - map(vec3(p.x, p.y - e, p.z)).x, map(vec3(p.x, p.y, p.z + e)).x - map(vec3(p.x, p.y, p.z - e)).x)); } vec4 castRay(in vec3 eye, in vec3 ray) { const int max_steps = 128; const float eps = 1e-6; float depth = NEAR; float material = -1.0; for (int i = 0; i < max_steps; i++) { vec4 result = map(eye + depth * ray); if (result.x < eps || result.x > FAR) { break; } depth += result.x; material = result.y; } if (depth > FAR) { material = -1.0; } return vec4(depth, material, 0.0, 0.0); } vec4 render(in vec3 eye, in vec3 ray) { vec4 result = castRay(eye, ray); float depth = result.x; float mID = result.y; vec3 pos = eye + depth * ray; vec3 colBikaBika1 = hsv2rgb(vec3(8.0 * iGlobalTime / MAX_TIME, 0.5, 1.0)); vec3 colBikaBika2 = hsv2rgb(vec3(4.0 * iGlobalTime / MAX_TIME, 1.0, 1.0)); vec3 colBikaBika3 = hsv2rgb(vec3(2.0 * iGlobalTime / MAX_TIME, 1.0, 1.0)); vec3 col1 = hsv2rgb(vec3(0.333 * floor(iGlobalTime / MAX_TIME), 1.0, 1.0)); vec3 col2 = hsv2rgb(vec3(0.333 * (1.0 + floor(iGlobalTime / MAX_TIME)), 1.0, 1.0)); vec3 col3 = hsv2rgb(vec3(0.333 * (2.0 + floor(iGlobalTime / MAX_TIME)), 1.0, 1.0)); col1 = mix(colBikaBika1, col1, mod(iGlobalTime, MAX_TIME) / MAX_TIME); col2 = mix(colBikaBika2, col2, mod(iGlobalTime, MAX_TIME) / MAX_TIME); col3 = mix(colBikaBika3, col3, mod(iGlobalTime, MAX_TIME) / MAX_TIME); vec3 col = vec3(0.0); if (mID > -1.0) { vec3 nor = getNormal(pos); float diff = 0.5 * pow2(dot(nor, vec3(.0, .0, 1.))) + 0.5; if (mID == 0.0) { col = col1 * diff; } if (mID == 1.0) { col = col2 * diff; } if (mID == 2.0) { col = col3 * diff; } if (mID == 3.0) { col = col1; } if (mID == 4.0) { col = col2; } if (mID == 5.0) { col = col3; } } return vec4(col, depth); } mat3 setCamera(in vec3 ro, in vec3 ta, float cr) { vec3 cw = normalize(ta - ro); vec3 cp = vec3(sin(cr), cos(cr), 0.0); vec3 cu = normalize(cross(cw, cp)); vec3 cv = normalize(cross(cu, cw)); return mat3(cu, cv, cw); } void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 p = 2.0 * (fragCoord.xy / iResolution.xy) - 1.0; p.x *= iResolution.x / iResolution.y; vec2 bure = vec2(-0.5); bure.x = random(vec2(0.3250, iGlobalTime)); bure.y = random(vec2(0.0160, iGlobalTime)); float t = mod(iGlobalTime, MAX_TIME); bure = pow2(exp(-t)) * bure * 10.0; vec3 ro = vec3(bure, 50.0); vec3 ta = vec3(0.0, 0.0, 0.0); mat3 ca = setCamera(ro, ta, .0); float fov = 60.0; float focal = 1.0 / tan(0.5 * fov * PI / 180.0); vec3 rd = ca * normalize(vec3(p.xy, focal)); vec3 prev = texture2D(backbuffer, fragCoord.xy / iResolution.xy).rgb; vec3 col = render(ro, rd).rgb; col = mix(col, prev, pow2(exp(-t))); col = pow(col, vec3(0.4545)); fragColor = vec4(col, 1.0); } void main() { mainImage(gl_FragColor, gl_FragCoord.xy); }