scene.org File Archive

File download

<root>­/­parties­/­2018­/­tokyodemofest18­/­glsl/life.txt

File size:
8 230 bytes (8.04K)
File date:
2018-12-04 14:46:55
Download count:
all-time: 522

Screenshot (by Demozoo)

Screenshot

Preview

precision highp float;

#define SHADERTOY 0
#define PI 3.141592654
#define saturate(a) clamp(a, 0., 1.)
#define range(a, b) (step(a, floor(time2)) * step(floor(time2), b))

const int maxIteration = 128;
const float fmaxIteration = float(maxIteration);

uniform float time;
uniform vec2 resolution;

float time0, time1, time2, zoom, a;
int iter;

float box(vec3 p, float b) {
    vec3 d = abs(p) - b;
    return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
}

mat2 rot(float a) {
    float c = cos(a), s = sin(a);
    return mat2(c, -s, s, c);
}

vec3 hue(float hue) {
    vec3 rgb = fract(hue + vec3(0., 2. / 3., 1. / 3.));
    rgb = abs(rgb * 2. - 1.);
    return clamp(rgb * 3. - 1., 0., 1.);
}

vec3 hsvToRgb(vec3 hsv) { return ((hue(hsv.x) - 1.) * hsv.y + 1.) * hsv.z; }

float hash11(float p) {
    vec3 p3 = fract(vec3(p) * .1031);
    p3 += dot(p3, p3.yzx + 19.19);
    return fract((p3.x + p3.y) * p3.z);
}

mat2 rot1, rot2, rot3, rot4;

vec2 ifs(vec3 p) {
    float d1 = 999., d2 = 999.;
    float range = .8, radius = .5 * (1. + zoom);

    const float maxIter = 8.;
    for (int i = int(maxIter); i > 0; i--) {
        if (i <= iter) {
            break;
        }

        float ratio = float(i) / maxIter;
        float bx = box(p, radius * ratio);
        d1 = mix(d1, min(d1, bx), float(i > iter + 1));
        d2 = min(d2, bx);

        ratio *= ratio;

        p.xz = abs(p.xz) - range * ratio * .7;
        p.xz *= rot1;
        p.yz *= rot3;
        p.yx *= rot2;

        p.yz = abs(p.yz) - range * ratio * .7;
        p.xz *= rot1;
        p.yz *= rot4;
        p.yx *= rot2;
    }

    return vec2(d1, d2);
}

float map(vec3 p) {
    vec2 d = ifs(p);
    return mix(mix(d.y, d.x, a), mix(d.x, d.y, a), step(time0, 5.5));
}

float calcAo(vec3 p, vec3 n) {
    float sca = 1.0, occ = 0.0;

    for (float i = 0.; i < 5.; i++) {
        float hr = 0.05 + i * 0.08;
        float dd = map(n * hr + p);
        occ += (hr - dd) * sca;
        sca *= 0.5;
    }

    return saturate(1.0 - occ);
}

vec3 intersect(vec3 ro, vec3 ray) {
    float t = 0.0;
    
    for (int i = 0; i < maxIteration; i++) {
        float res = abs(map(ro + ray * t));
        if (res < 0.005) return vec3(t, res, i);
        t += res;
    }

    return vec3(-1.0);
}

vec3 normal(vec3 pos, float e) {
    vec2 eps = vec2(1.0, -1.0) * 0.5773 * e;

    return normalize(eps.xyy * map(pos + eps.xyy) +
                     eps.yyx * map(pos + eps.yyx) +
                     eps.yxy * map(pos + eps.yxy) +
                     eps.xxx * map(pos + eps.xxx));
}

mat3 createCamera(vec3 ro, 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);
}

float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }

float noise(vec2 x) {
	vec2 i = floor(x), f = fract(x);

	float a = hash(i);
	float b = hash(i + vec2(1.0, 0.0));
	float c = hash(i + vec2(0.0, 1.0));
	float d = hash(i + vec2(1.0, 1.0));

	vec2 u = f * f * (3.0 - 2.0 * f);
	return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

float fbm(vec2 p) {
	const mat2 m2 = mat2(0.8, -0.6, 0.6, 0.8);

	p.xy += 0.1 * time1;

	float f = 0.5000 * noise(p); p = m2 * p * 2.02;
	f += 0.2500 * noise(p); p = m2 * p * 2.03;
	f += 0.1250 * noise(p); p = m2 * p * 2.01;
	f += 0.0625 * noise(p);
	return f / 0.9375;
}

vec3 sky(vec3 ro, vec3 ray) {
    vec3 col = vec3(0.);

    float rd = ray.y + 0.3;
    col = mix(col, vec3(2.0, 0.25, 2.0), 0.5 * smoothstep(0.5, 0.8, fbm((ro.xz + ray.xz * (250000.0 - ro.y) / rd) * 0.000008)));
    col = mix(col, vec3(0.), pow(1.0 - max(rd, 0.0), 4.0));
    
    col = mix(vec3(0.), col, saturate(time1 * 3. - 4.));
    col = mix(col, vec3(0.), saturate(time1 - 5.25));
    return col * 1.3;
}

#define edge(start, end, sStart, sEnd, ecol) if (range(start, end) > 0.) { showEdge = 1.; float offs = pos.y - mix(sStart, sEnd, 0.025 + saturate(time2 - start)); edgeColor = ecol; edgeIntensity = mix(0., edgeIntensity, saturate(1. - abs(offs))); col = mix(col, objectColor, saturate(1. - (offs + 1.5))); }

vec3 render(vec2 p) {
    float t = time0 * 0.7 - 1.;
    float offs = mix(1., hash11(max(1., floor(t * 4.))), smoothstep(0., .5, time0));
    vec3 ro = vec3(cos(t * 3.5) * 11., sin(t * 3.9) * 4.5, sin(t * 1.5) * 10.) * 0.7;

    t = time1 * 0.7;
    offs = mix(mix(1., hash11(max(1., floor(t * 4.))), step(0., time1)), 1., step(4.6, time1));
    ro = mix(ro, vec3(cos(t * 1.5) * 11. * offs, sin(t * 2.) * 4. * offs * 2., sin(t * 1.5) * 20. * offs) * 0.9, smoothstep(0.7, 1., time1));
    ro = mix(ro, vec3(cos(t * 1.5) * 11., sin(t * 3.9) * 4., sin(t * 1.5) * 10.), smoothstep(4.6, 5.5, time1));
    ro = mix(ro, vec3(5., 3., 5.), saturate(time1 - 6.7));

    vec3 ta = vec3(0.0, 0.0, (sin(t * 0.55) * 0.5 + 0.5) * 2.0);
    ta = mix(ta, vec3(0.), saturate(time1 - 6.7));

    mat3 cm = createCamera(ro, ta, 0.);
    vec3 ray = cm * normalize(vec3(p, 4.0));

    vec3 res = intersect(ro, ray);
    if (res.y < -0.5) {
        return sky(ro, ray);
    }

    vec3 pos = ro + ray * res.x;
    vec3 nor = normal(pos, 0.008);

    float glowIntensity = saturate(pow(abs(1. - abs(dot(nor, ray))), 1.));
    vec3 objectColor = (vec3(.003, .001, .0095)
            * pow(1. / res.z * 1.5, -1.8) + glowIntensity * vec3(.1, .25, .3)) * res.x * 0.3
            * calcAo(pos, nor)
            + sky(ro, normalize(reflect(ray, nor))) * .4 * (1. - zoom);

    float a = smoothstep(0.3, 0.7, pow(fract(time0 * 3.), 0.4));
    float edgeThreshold = mix(0.02, 0.03, (1. - a) * (1. - zoom));
    float edgeIntensity = smoothstep(edgeThreshold - 0.01, edgeThreshold, length(nor - normal(pos, .015)));

    float noShade = range(-10., 3.);
    vec3 col = mix(objectColor, vec3(0.), noShade);

    float showEdge = 0.;
    vec3 edgeColor = vec3(1.);
    vec3 rainbow = hue(pos.z / 2.);
    edge(3., 3.5, -2., 2.2, hue(abs(offs) / 5. + .5) * 2.)
    edge(6., 6.5, -3.5, 2., rainbow)
    edge(5., 5.5, -3.5, 2., rainbow)
    edge(10., 10.5, -3.5, 2., rainbow)
    edge(11.5, 12., -3.5, 2.4, rainbow)

    if (time2 > 16.5) {
        showEdge = 1.;
        offs = pos.y - mix(-3.5, 4., saturate(time2 - 16.5));
        col = mix(objectColor, vec3(0.), saturate(1. - offs));
        edgeIntensity = mix(0., edgeIntensity, saturate(1. - (offs + .6)));
    }

    col += edgeColor * edgeIntensity * step(1., zoom + noShade + showEdge);
    col = mix(col, 1. - col, zoom);
    return col;
}

vec2 shake(float t) {
    float s = t * 50.0;
    return (vec2(hash11(s), hash11(s + 11.0)) * 2.0 - 1.0) * exp(-5.0 * t) * 0.2;
}

vec3 vignette(vec2 p) {
    p *= 1.0 - p.yx;
    return vec3(1.2, 1.1, .85) * pow(16. * p.x * p.y * (1. - p.x) * (1. - p.y), 0.125);
}

void entryPoint(in vec2 coord, in vec2 resolution, in float time, out vec4 color) {
    vec2 p = (coord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y);

    time -= 3.;
    time0 = mod(time * 0.4, 11.);
    time1 = time0 - 11. / 4.;
    time2 = time1 * 0.7 * 4.;

    float t = time0 * 3.;
    iter = int(mix(clamp(14. - floor(t), 0., 7.), min(8., floor(t) - 24.), step(24., floor(t))));
    a = mix(1., smoothstep(0.3, 0.7, pow(fract(t), 0.4)), step(7.5, t));

    t = time1 * 3.;
    float angle = step(1.2, time1) * (floor(t + 0.5) + smoothstep(0.3, 0.7, pow(fract(t + 0.5), 0.4)));

    rot1 = rot(0.785397);
    rot2 = rot(1.7079);
    rot3 = rot(angle * 1.2 + 424. + step(7.035716, time0) * 3.);
    rot4 = rot(angle * 1.2 + 226.);

    zoom = range(8., 9.) + range(11., 11.5);

    p = mix(p, vec2(1. + hash11(p.y) * 10., p.y), saturate(time0 - 10.33) * 5.);
    p += shake(fract(time1 * 2.)) * 0.10;
    p *= 1.0 + 5. * pow(length(p), 1.5) * zoom;

    vec3 col = render(p);
    col *= vignette(coord.xy / resolution.xy);
    col = mix(col, vec3(0.), saturate(time0 - 10.33) * 10. + step(time, 0.));

    color = vec4(col, 1.0);
}

void
#if SHADERTOY == 1
mainImage(out vec4 fragColor, in vec2 fragCoord) { entryPoint(fragCoord.xy, iResolution.xy, iTime, fragColor); }
#else
main(void) { entryPoint(gl_FragCoord.xy, resolution.xy, time, gl_FragColor); }
#endif