Preview
#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); }