scene.org File Archive

File download

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

File size:
6 524 bytes (6.37K)
File date:
2018-12-04 14:46:54
Download count:
all-time: 473

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