scene.org File Archive

File download

<root>­/­parties­/­2016­/­tokyodemofest16­/­glsl_graphics_compo/indras_bubbles.txt

File size:
10 123 bytes (9.89K)
File date:
2016-02-24 05:45:01
Download count:
all-time: 659

Preview

precision mediump float;
uniform float time;
uniform vec2  mouse;
uniform vec2  resolution;

const float MTL_PSEUDO_KLEINIAN = 1.;
const float MTL_KLEIN = 2.;

const vec3 ROTATION_AXIS = normalize(vec3(0.1, 1, 0.5));

vec3 rotate(vec3 p, float angle){
  float s = sin(angle);
  float c = cos(angle);
  float r = 1.0 - c;
  mat3 m = mat3(ROTATION_AXIS.x * ROTATION_AXIS.x * r + c,
                ROTATION_AXIS.y * ROTATION_AXIS.x * r + ROTATION_AXIS.z * s,
                ROTATION_AXIS.z * ROTATION_AXIS.x * r - ROTATION_AXIS.y * s,
                ROTATION_AXIS.x * ROTATION_AXIS.y * r - ROTATION_AXIS.z * s,
                ROTATION_AXIS.y * ROTATION_AXIS.y * r + c,
                ROTATION_AXIS.z * ROTATION_AXIS.y * r + ROTATION_AXIS.x * s,
                ROTATION_AXIS.x * ROTATION_AXIS.z * r + ROTATION_AXIS.y * s,
                ROTATION_AXIS.y * ROTATION_AXIS.z * r - ROTATION_AXIS.x * s,
                ROTATION_AXIS.z * ROTATION_AXIS.z * r + c);
  return m * p;
}

vec2 opUnion(const vec2 d1, const vec2 d2){
  return (d1.x < d2.x) ? d1 : d2;
}

const vec3 spherePos1 = vec3(5, 5, 0);
const vec3 spherePos2 = vec3(5, -5, 0);
const vec3 spherePos3 = vec3(-5, 5, 0);
const vec3 spherePos4 = vec3(-5, -5, 0);
const vec3 spherePos5 = vec3(0, 0, 7.071);
const vec3 spherePos6 = vec3(0, 0, -7.071);
const float SPHERE_R = 5.;
const float SPHERE_R2 = SPHERE_R * SPHERE_R;

int kleinIteration = 8;
float kleinSphereR = 5.;
float loopNum = 0.;
const int SPHERE_NUM = 6;
const vec3 KLEIN_POS = vec3(0, 0, -5);
const int MAX_KLEIN_ITARATION = 20;
const vec4 initialSp = vec4(-1.);
vec2 distKlein(vec3 pos){
  pos = rotate(pos + KLEIN_POS, radians(time * 30.));
  loopNum = 0.;
  float dr = 1.;
  vec4 sp;
  for(int i = 0 ; i < MAX_KLEIN_ITARATION ; i++){
    if(i > kleinIteration) break;
    sp = initialSp;

    float d = distance(pos, spherePos1);
    sp = (d < SPHERE_R) ? vec4(spherePos1, d) : sp;
    d = distance(pos, spherePos2);
    sp = (d < SPHERE_R) ? vec4(spherePos2, d) : sp;
    d = distance(pos, spherePos3);
    sp = (d < SPHERE_R) ? vec4(spherePos3, d) : sp;
    d = distance(pos, spherePos4);
    sp = (d < SPHERE_R) ? vec4(spherePos4, d) : sp;
    d = distance(pos, spherePos5);
    sp = (d < SPHERE_R) ? vec4(spherePos5, d) : sp;
    d = distance(pos, spherePos6);
    sp = (d < SPHERE_R) ? vec4(spherePos6, d) : sp;

    if(sp.x == -1.){
      break;
    }else{
      vec3 diff = (pos - sp.xyz);
      dr *= SPHERE_R2 / dot(diff, diff);
      pos = (diff * SPHERE_R2)/(sp.w * sp.w) + sp.xyz;
      loopNum++;
    }
  }
  return vec2((length(pos) - kleinSphereR) / abs(dr) * 0.08, MTL_KLEIN);
}


vec3 orb;
const vec3 PSEUDO_KLEINIAN_POS = vec3(10, 6, 2.5);
const vec3 TRAP_POINT = vec3(1000.);
const vec3 PSEUDO_KLEINIAN_CUBE_SIZE = vec3(9.2436, 9.0756, 9.2436);
const float PSEUDO_KLEINIAN_SIZE = 110.;
vec2 distPseudoKleinian(vec3 p){
  orb = TRAP_POINT;
  p = p + PSEUDO_KLEINIAN_POS;
  float DEfactor = 1.;
  vec3 ap = p + 1.;
  for(int i = 0; i < 7 ; i++){
    ap = p;
    p= -p + 2. * clamp(p, -PSEUDO_KLEINIAN_CUBE_SIZE, PSEUDO_KLEINIAN_CUBE_SIZE);
    orb = min( orb, vec3(abs(p)));
    float k = PSEUDO_KLEINIAN_SIZE / dot(p, p);
    p *= k;
    DEfactor *= k;
  }
  return vec2(abs(0.5*abs(p.z)/DEfactor), MTL_PSEUDO_KLEINIAN);
}

vec3 calcRay (const vec3 eye, const vec3 target, const vec3 up, const float fov,
              const float width, const float height, const vec2 coord){
  float imagePlane = (height * .5) / tan(fov * .5);
  vec3 v = normalize(target - eye);
  vec3 xaxis = normalize(cross(v, up));
  vec3 yaxis =  normalize(cross(v, xaxis));
  vec3 center = v * imagePlane;
  vec3 origin = center - (xaxis * (width  *.5)) - (yaxis * (height * .5));
  return normalize(origin + (xaxis * coord.x) + (yaxis * (height - coord.y)));
}

const vec4 K = vec4(1.0, .666666, .333333, 3.0);
vec3 hsv2rgb(const vec3 c){
  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);
}

vec3 eye = vec3(0, 0, 800);
vec3 target = vec3(0, 0, 7);
const vec3 up = vec3(0, 1, 0);
const float fov = radians(60.);

vec2 distFunc(vec3 p){
  return opUnion(distPseudoKleinian(p), distKlein(p));;
}

const vec2 d = vec2(0.01, 0.);
vec3 getNormal(const vec3 p){
  return normalize(vec3(distFunc(p + d.xyy).x - distFunc(p - d.xyy).x,
                        distFunc(p + d.yxy).x - distFunc(p - d.yxy).x,
                        distFunc(p + d.yyx).x - distFunc(p - d.yyx).x));
}

const float PI_4 = 12.566368;
const vec3 LIGHTING_FACT = vec3(0.1);
vec3 diffuseLighting(const vec3 p, const vec3 n, const vec3 diffuseColor,
                     const vec3 lightPos, const vec3 lightPower){
  vec3 v = lightPos - p;
  float dot = dot(n, normalize(v));
  float r = length(v);
  return (dot > 0.) ?
    (lightPower * (dot / (PI_4 * r * r))) * diffuseColor
    : LIGHTING_FACT * diffuseColor;
}

const vec3 lightPos = vec3(100., 100., 100.);
const vec3 lightPos2 = vec3(-100., -100., -100);
const vec3 lightPower = vec3(10.);
const vec3 lightPower2 = vec3(10.);

vec3 lighting(const float kd, const vec3 matColor, vec3 l,
              const vec3 intersection, const vec3 normal){
  return (kd > 0.) ?
    l + (diffuseLighting(intersection, normal, matColor,
                         lightPos, lightPower) * kd) +
    (diffuseLighting(intersection, normal, matColor,
                     lightPos2, lightPower2) * kd)
    : l;
}

const int MAX_MARCHING_LOOP = 700;
int marchingLoop = 700;
vec3 march(const vec3 origin, const  vec3 ray, const float threshold){
  vec3 rayPos = origin;
  vec2 dist = vec2(0., -1);
  float rayLength = 0.;
  for(int i = 0 ; i < MAX_MARCHING_LOOP ; i++){
    dist = distFunc(rayPos);
    rayLength += dist.x;
    rayPos = origin + ray * rayLength ;
    if(dist.x < threshold || i > marchingLoop) break;
  }
  return vec3(dist, rayLength);
}

const float fogStart = 10.;
const float fogEnd = 100.;
const float FOG_END_START_RECIPROCAL = 1. / (fogEnd - fogStart);
const vec3 fogf = vec3(1.);
const vec3 BLACK = vec3(0);
int reflectNum = 3;
vec3 trace(vec3 eye, vec3 ray){
  vec3 l = BLACK;
  float coeff = 1.;
  for(int depth = 0 ; depth < 5 ; depth++){
    if(depth >= reflectNum) break;
    float threshold = 0.003 * pow(1.5 , float(depth));
    vec3 result = march(eye, ray, threshold);
    vec3 intersection = eye + ray * result.z;
    vec3 matColor = vec3(0);
    vec3 normal = getNormal(intersection);
    if(result.x < threshold){
      float ks = 0.;
      if(result.y == MTL_KLEIN){
        ks = (loopNum < 4.) ? 0.5 * coeff : 0.;
        matColor = hsv2rgb(vec3(0.1 + loopNum * 0.1 , 1., 1.));
      }else{
        matColor = vec3(clamp(6.0*orb.y,0.0,1.0), clamp(1.0-2.0*orb.z,0.0,1.0), .5);
        ks = (matColor.r > 0.8 &&
              matColor.g > 0.8 ) ? 0.8 * coeff : 0.;
      }

      if(ks > 0.){
        marchingLoop -= 200;
        l = mix(fogf , lighting(1. - ks, matColor, l, intersection, normal),
                clamp((fogEnd - result.z) * FOG_END_START_RECIPROCAL, 0.5, 1.0));
        coeff = ks;
        eye = eye + ray * result.z * 0.9;
        ray = reflect(ray, normal);
      }else{
        l = mix(fogf , lighting(1. - ks, matColor, l, intersection, normal),
                clamp((fogEnd - result.z) * FOG_END_START_RECIPROCAL, 0.5, 1.0));
        break;
      }
    }else{
        l = mix(fogf , l, clamp((fogEnd - result.z) * FOG_END_START_RECIPROCAL, 0.5, 1.0));
      break;
    }
  }
  return l;
}

void expandSphere(const float t,
                  const float minR, const float maxR, const int iteration){
  kleinIteration = iteration;
  kleinSphereR = mix(minR, maxR,
                     smoothstep(minR, maxR, t));
}

void shrinkSphere(const float t,
                  const float minR, const float maxR, const int iteration){
  kleinIteration = iteration;
  kleinSphereR = mix(maxR, minR,
                     smoothstep(minR, maxR, minR + t));
}

const float DISPLAY_GAMMA_COEFF = 1. / 2.2;
vec3 gammaCorrect(vec3 rgb) {
  return vec3((min(pow(rgb.r, DISPLAY_GAMMA_COEFF), 1.)),
              (min(pow(rgb.g, DISPLAY_GAMMA_COEFF), 1.)),
              (min(pow(rgb.b, DISPLAY_GAMMA_COEFF), 1.)));
}

const vec2 constantList = vec2(1.0, 0.0);
const float eyeRad = 8.9;
void main(){
  float t = mod(time, 85.);
  const float minR = 0.;
  const float maxR = 3.;
  vec3 eye = vec3(eyeRad * sin(time), 0., 7. + eyeRad *  cos(time));
    target = -(eye - target ) + vec3(0. , (mouse.y - 0.5) * 10., 0);
  if(t < 3.){
    expandSphere(t, minR, maxR, 0);
  }else if(t < 6.){
    shrinkSphere(t - 3., minR, maxR, 0);
  }else if(t < 9.){
    expandSphere(t - 6., minR, maxR, 1);
  }else if(t < 12.){
    shrinkSphere(t - 9., minR, maxR, 1);
  }else if(t < 15.){
    expandSphere(t - 12., minR, maxR, 2);
  }else if(t < 18.){
    shrinkSphere(t - 15., minR, maxR, 2);
  }else if(t < 21.){
    expandSphere(t - 18., minR, maxR, 3);
  }else if(t < 24.){
    shrinkSphere(t - 21., minR, maxR, 3);
  }else if(t < 27.){
    expandSphere(t - 24., minR, maxR, 4);
  }else if(t < 30.){
    shrinkSphere(t - 27., minR, maxR, 4);
  }else if(t < 40.){
    expandSphere(t - 30., minR, 5., 12);
    reflectNum = 4;
  }else if(t < 55.){
    expandSphere(t - 40., 5., 6.3, 12);
    reflectNum = 4;
  }else if(t < 65.){
    shrinkSphere(t - 55., 2.0833, 6.5, 8);
  }else if(t < 70.){
    shrinkSphere(t - 65., minR, 2.0833, 8);
  }else if(t < 71.){
    kleinSphereR = 0.;
    kleinIteration = 7;
  }else if(t < 72.){
    kleinSphereR = 0.;
    kleinIteration = 6;
  }else if(t < 73.){
    kleinSphereR = 0.;
    kleinIteration = 5;
  }else if(t < 76.){
    kleinSphereR = 0.;
    kleinIteration = 4;
  }else if(t < 78.){
    kleinSphereR = 0.;
    kleinIteration = 3;
  }else if(t < 80.){
    kleinSphereR = 0.;
    kleinIteration = 2;
  }else if(t < 82.){
    kleinSphereR = 0.;
    kleinIteration = 1;
  }else{
    kleinSphereR = 0.;
    kleinIteration = 0;
  }
  const vec2 coordOffset = vec2(0.5);
  vec3 ray = calcRay(eye, target, up, fov,
                     resolution.x, resolution.y,
                     gl_FragCoord.xy + coordOffset);

  gl_FragColor = vec4(gammaCorrect(trace(eye, ray)), 1.);
}