scene.org File Archive

File download

<root>­/­parties­/­2023­/­sessions23­/­glsl/w0nyv_glsl_compo_v3.txt

File size:
14 684 bytes (14.34K)
File date:
2023-04-30 12:51:04
Download count:
all-time: 205

Preview

precision highp float;
uniform vec2 resolution;
uniform vec2 mouse;
uniform float time;
uniform sampler2D backbuffer;

//--reference--
//https://wgld.org/
//https://iquilezles.org/articles/distfunctions/
//https://www.shadertoy.com/view/NtdXD4
//https://www.osar.fr/notes/logspherical/
//https://qiita.com/keim_at_si/items/c2d1afd6443f3040e900
//https://scrapbox.io/0b5vr/Plasma_Effect
//-------------

const int MAT_BODY = 0;
const int MAT_MOUTH = 1;
const int MAT_EYE_BALL = 2;
const int MAT_GAMING = 3;
const int MAT_DAIZA = 4;

struct MarchResult {
  float dist;
  int material;
};

vec3 hsv2rgb(float h, float s, float v) {
  return ((clamp(abs(fract(h+vec3(0,2,1)/3.)*6.-3.)-1.,0.,1.)-1.)*s+1.)*v;
}

mat2 rot(float r) {
  return mat2(cos(r), sin(r), -sin(r), cos(r));
}

float smoothUnion(float d1, float d2, float k) {
  float h = clamp(0.5 + 0.5 * (d2 - d1)/k, 0.0, 1.0);
  return mix(d2, d1, h) - k*h*(1.0-h);
}

float smoothSubtraction(float d1, float d2, float k) {
  float h = clamp(0.5 - 0.5 * (d2+d1)/k, 0.0, 1.0);
  return mix(d2, -d1, h) + k*h*(1.0-h);
}

float sdSphere(vec3 p, float r) {
  return length(p) - r;
}

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

float sdHexPrism(vec3 p, vec2 h) {
  vec3 k = vec3(-0.8660254, 0.5, 0.57735);
  p = abs(p);
  p.xy -= 2.0 * min(dot(k.xy, p.xy), 0.0) * k.xy;
  vec2 d = vec2(
    length(p.xy-vec2(clamp(p.x, -k.z*h.x, k.z*h.x), h.x)) * sign(p.y-h.x),
    p.z-h.y);
  return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}

float sdCapsule(vec3 p, vec3 a, vec3 b, float r) {
  vec3 pa = p - a, ba = b - a;
  float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
  return length(pa - ba*h) - r;
}

float sdRoundCone(vec3 p, float r1, float r2, float h) {
  float b = (r1-r2)/h;
  float a = sqrt(1.0-b*b);
  
  vec2 q = vec2(length(p.xz), p.y);
  float k = dot(q, vec2(-b, a));
  if(k<0.0) return length(q) - r1;
  if(k>a*h) return length(q - vec2(0.0, h)) - r2;
  return dot(q, vec2(a, b)) - r1;
}

float sdEye(vec3 p, float r) {
  
  float d = sdSphere(p, r);
  float d2 = sdSphere(p + vec3(0.0, -0.025, -r), r * 0.7);

  float outer = smoothSubtraction(d2, d, 0.02);
  
  return outer;

}

float sdMouth(vec3 p, float smile) {
  float k = smile;
  float c = cos(k*p.x);
  float s = sin(k*p.x);
  mat2 m = mat2(c, -s, s, c);
  vec3 q = vec3(m*p.xy, p.z);
  return sdCapsule(q, vec3(0.25, 0.0, 0.5), vec3(-0.25, 0.0, 0.5), 0.025);
}

vec2 footOffset1(float offset) {
  return vec2(
    min(sin(time*5.0 + offset) * -0.5, 0.18),
    max(sin(time*5.0 + offset) * -0.5, -0.18)
  );
}

vec2 footOffset2(float offset) {
  return vec2(
    abs(sin(time*5.0 + offset)) * 0.5 * clamp(sin(time*5.0 + offset), 0.0, 1.0),
    abs(sin(time*5.0 + offset)) * 0.5 * clamp(sin(time*-5.0 - offset), 0.0, 1.0)
  );
}

float sdFoot(vec3 p) {

  vec3 offset = vec3(0.0, 0.4, 0.8);

  float upperFootR1 = sdCapsule(p, vec3(0.7 + footOffset1(offset.x).x, -0.1 + footOffset2(offset.x).x, 0.0), vec3(1.0, -0.2 + footOffset2(offset.x).x, 0.0), 0.065);
  float lowerFootR1 = sdCapsule(p, vec3(1.0, -0.2 + footOffset2(offset.x).x, 0.0), vec3(1.0, -0.5 + footOffset2(offset.x).x, 0.0), 0.065);
  float footR1 = smoothUnion(upperFootR1, lowerFootR1, 0.025);
  
  float upperFootR2 = sdCapsule(p, vec3(0.7 + footOffset1(offset.y).x, -0.1 + footOffset2(offset.y).x, 0.1), vec3(1.0, -0.2 + footOffset2(offset.y).x, 0.25), 0.065);
  float lowerFootR2 = sdCapsule(p, vec3(1.0, -0.2 + footOffset2(offset.y).x, 0.25), vec3(1.0, -0.5 + footOffset2(offset.y).x, 0.25), 0.065);
  float footR2 = smoothUnion(upperFootR2, lowerFootR2, 0.025);
  
  float upperFootR3 = sdCapsule(p, vec3(0.7 + footOffset1(offset.z).x, -0.1 + footOffset2(offset.z).x, -0.1), vec3(1.0, -0.2 + footOffset2(offset.z).x, -0.25), 0.065);
  float lowerFootR3 = sdCapsule(p, vec3(1.0, -0.2 + footOffset2(offset.z).x, -0.25), vec3(1.0, -0.5 + footOffset2(offset.z).x, -0.25), 0.065);
  float footR3 = smoothUnion(upperFootR3, lowerFootR3, 0.025);
  
  float upperFootL1 = sdCapsule(p, vec3(-0.7 + footOffset1(offset.x).y, -0.1 + footOffset2(offset.x).y, 0.0), vec3(-1.0, -0.2 + footOffset2(offset.x).y, 0.0), 0.065);
  float lowerFootL1 = sdCapsule(p, vec3(-1.0, -0.2 + footOffset2(offset.x).y, 0.0), vec3(-1.0, -0.5 + footOffset2(offset.x).y, 0.0), 0.065);
  float footL1 = smoothUnion(upperFootL1, lowerFootL1, 0.025);
  
  float upperFootL2 = sdCapsule(p, vec3(-0.7 + footOffset1(offset.y).y, -0.1 + footOffset2(0.0).y, 0.1), vec3(-1.0, -0.2 + footOffset2(offset.y).y, 0.25), 0.065);
  float lowerFootL2 = sdCapsule(p, vec3(-1.0, -0.2 + footOffset2(offset.y).y, 0.25), vec3(-1.0, -0.5 + footOffset2(offset.y).y , 0.25), 0.065);
  float footL2 = smoothUnion(upperFootL2, lowerFootL2, 0.025);
  
  float upperFootL3 = sdCapsule(p, vec3(-0.7 + footOffset1(offset.z).y, -0.1 + footOffset2(offset.z).y, -0.1), vec3(-1.0, -0.2 + footOffset2(offset.z).y, -0.25), 0.065);
  float lowerFootL3 = sdCapsule(p, vec3(-1.0, -0.2 + footOffset2(offset.z).y, -0.25), vec3(-1.0, -0.5 + footOffset2(offset.z).y, -0.25), 0.065);
  float footL3 = smoothUnion(upperFootL3, lowerFootL3, 0.025);
  
  float footR = min(min(footR1, footR2), footR3);
  float footL = min(min(footL1, footL2), footL3);

  return min(footR, footL);
}

float sdEye(vec3 p) {
  float eyeStickR = sdCapsule(p, vec3(0.2, 0.0, 0.0), vec3(0.2, 1.0, 0.0), 0.05);
  float eyeStickL = sdCapsule(p, vec3(-0.2, 0.0, 0.0), vec3(-0.2, 1.0, 0.0), 0.05);
  float eyeR = smoothUnion(eyeStickR, sdEye(p + vec3(-0.19, -1.0, 0.0), 0.15), 0.1);
  float eyeL = smoothUnion(eyeStickL, sdEye(p + vec3(0.19, -1.0, 0.0), 0.15), 0.1);
  return min(eyeR, eyeL);
}

float sdScissors(vec3 p, vec3 offset, float angle) {
  vec3 p4arm = p + offset;
  p4arm.xy *= rot(angle);
  return sdRoundCone(p4arm, 0.1, 0.05, 0.3);
}

float sdArm(vec3 p) {
  float armStickR = sdCapsule(p, vec3(0.5, 0.0, 0.0), vec3(0.9, 0.7, 0.0), 0.065);
  float armStickL = sdCapsule(p, vec3(-0.5, 0.0, 0.0), vec3(-0.9, 0.7, 0.0), 0.065);
  
  float scissorsR = smoothUnion(
                      sdScissors(p, vec3(-0.9, -0.75, 0.0), acos(-1.0)/4.0 * max(abs(sin(time * 5.0)), 0.3)), 
                      sdScissors(p, vec3(-0.9, -0.75, 0.0), acos(-1.0)/-4.0 * max(abs(sin(time * 5.0)), 0.3)), 
                      0.05
                    );
  float scissorsL = smoothUnion(
                      sdScissors(p, vec3(0.9, -0.75, 0.0), acos(-1.0)/4.0 * max(abs(sin(time * 5.0 + acos(-1.0) / 2.0)), 0.3)), 
                      sdScissors(p, vec3(0.9, -0.75, 0.0), acos(-1.0)/-4.0 * max(abs(sin(time * 5.0 + acos(-1.0) / 2.0)), 0.3)),
                      0.05
                    );

  float armR = smoothUnion(armStickR, scissorsR, 0.1);
  float armL = smoothUnion(armStickL, scissorsL, 0.1);

  return min(armR, armL);
}

float sdO(vec3 p, float size) {
  float s = size * 2.0;
  
  float o1 = sdBox(p + vec3(0.0, -s*2.0, 0.0), vec3(size));
  float o2 = sdBox(p + vec3(-s, -s*2.0, 0.0), vec3(size));
  float o3 = sdBox(p + vec3(s, -s*2.0, 0.0), vec3(size));

  float o4 = sdBox(p + vec3(-s*2.0, 0.0, 0.0), vec3(size));
  float o5 = sdBox(p + vec3(-s*2.0, -s, 0.0), vec3(size));
  float o6 = sdBox(p + vec3(-s*2.0, s, 0.0), vec3(size));

  float o7 = sdBox(p + vec3(0.0, s*2.0, 0.0), vec3(size));
  float o8 = sdBox(p + vec3(-s, s*2.0, 0.0), vec3(size));
  float o9 = sdBox(p + vec3(s, s*2.0, 0.0), vec3(size));

  float o10 = sdBox(p + vec3(s*2.0, 0.0, 0.0), vec3(size));
  float o11 = sdBox(p + vec3(s*2.0, -s, 0.0), vec3(size));
  float o12 = sdBox(p + vec3(s*2.0, s, 0.0), vec3(size));
  
  float o123 = min(min(o1, o2), o3);
  float o456 = min(min(o4, o5), o6);
  float o789 = min(min(o7, o8), o9);
  float o101112 = min(min(o10, o11), o12);

  return min(min(min(o123, o456), o789), o101112);
}

float sdBikkuri(vec3 p, float size) {
  
  float s = size * 2.0;
  
  vec3 p4b = p;
  float b1 = sdBox(p4b, vec3(size));
  float b2 = sdBox(p4b + vec3(0.0, s * 2.0, 0.0), vec3(size));
  float b3 = sdBox(p4b + vec3(0.0, -s, 0.0), vec3(size));
  float b4 = sdBox(p4b + vec3(0.0, -s * 2.0, 0.0), vec3(size));

  return min(min(min(b1, b2), b3), b4);
}

float sdLetter(vec3 p) {
  
  p.y -= 20.0;
  
  float scl = 3.0/acos(-1.0);
  
  vec2 pos2d = p.xz;
  float r = length(pos2d);
  pos2d = vec2(log(r), atan(pos2d.y, pos2d.x));
  
  pos2d.x += time / 2.0;
  pos2d.y += time / 8.0;

  pos2d *= scl;
  pos2d = mod(pos2d, 1.0) - 0.5;
  float mul = r/scl;
  p = vec3(pos2d.y, p.y / mul, pos2d.x);

  float size = 0.01;
  float s = size * 2.0;
  
  vec3 p4y = p + vec3(s*15.0 + size*3.0, 0.0, 0.0);
  float y1 = sdBox(p4y, vec3(size));
  float y2 = sdBox(p4y + vec3(s,-s,0.0), vec3(size));
  float y3 = sdBox(p4y + vec3(-s,-s,0.0), vec3(size));
  float y4 = sdBox(p4y + vec3(0.0,s,0.0), vec3(size));
  float y5 = sdBox(p4y + vec3(0.0,s * 2.0,0.0), vec3(size));
  float y6 = sdBox(p4y + vec3(s * 2.0,-s * 2.0,0.0), vec3(size));
  float y7 = sdBox(p4y + vec3(-s * 2.0,-s * 2.0,0.0), vec3(size));
  
  float y = min(min(min(min(min(min(y1, y2), y3), y4), y5), y6), y7);
  
  float b = min(
              sdBikkuri(p + vec3(-s*15.0 + size*-3.0, 0.0, 0.0), size),
              sdBikkuri(p + vec3(-s*10.0 + size*-2.0, 0.0, 0.0), size)
            );
  
  float o1 = sdO(p + vec3(s*10.0 + size*2.0, 0.0, 0.0), size);
  float o2 = sdO(p + vec3(s*5.0 + size, 0.0, 0.0), size);
  float o3 = sdO(p + vec3(0.0, 0.0, 0.0), size);
  float o4 = sdO(p + vec3(-s*5.0 - size, 0.0, 0.0), size);

  float o = min(min(min(o1, o2), o3), o4);

  float letter = min(min(y, o), b);
  
  return letter * mul;
}

MarchResult crabMap(vec3 p, float dist) {
  MarchResult result;
  result.dist = dist;
  
  vec3 p4body = p;
  
  p4body.y -= abs(sin(time * 5.0 + 0.1)) * 0.3;
  p4body.x += sin(time * 5.0 - 0.1) * 0.3;
  
  float body = sdCapsule(p4body, vec3(0.25, 0.0, 0.0), vec3(-0.25, 0.0, 0.0), 0.5);
  
  float eye = sdEye(p4body);
  
  float foot = sdFoot(p);

  float arm = sdArm(p4body);

  body = smoothUnion(body, eye, 0.3);
  body = smoothUnion(body, foot, 0.1);
  body = smoothUnion(body, arm, 0.1);
  
  float eyeBall = min(sdSphere(p4body + vec3(0.19, -1.0, -0.15*0.4), 0.15 * 0.6), sdSphere(p4body + vec3(-0.19, -1.0, -0.15*0.4), 0.15 * 0.6));
  float eyeBallBlack = min(sdSphere(p4body + vec3(0.19, -1.0, -0.325*0.4), 0.05 * 0.6), sdSphere(p4body + vec3(-0.19, -1.0, -0.325*0.4), 0.05 * 0.6));

  float mouth = sdMouth(p4body, 1.0 + abs(sin(p.z*2.0 + time)));
  
  float d = body;
  if(d < result.dist) {
    result.dist = d;
    
    result.material = MAT_BODY;
    
  }
  
  d = mouth;
  if(d < result.dist) {
    result.dist = d;
    result.material = MAT_MOUTH;
  }
  
  d = eyeBall;
  if(d < result.dist) {
    result.dist = d;
    result.material = MAT_EYE_BALL;
  }
  
  d = eyeBallBlack;
  if(d < result.dist) {
    result.dist = d;
    result.material = MAT_MOUTH;
  }
  
  return result;
}

MarchResult map(vec3 p) {
  
  vec3 p2 = p;

  MarchResult result;
  result.dist = 1E9;
  
  p.z -= time * 4.0;
  if(floor(mod(time/2.0, 8.0)) == 7.0) {
    p.y += sin(floor(p.z/4.0) + floor(p.x/8.0)*2.0 + time * 15.0) * 2.0;
  } else {
    p.y += sin(floor(p.z/4.0) + floor(p.x/8.0)*2.0 + time * 8.0)*0.5;
  }
  p.z = mod(p.z, 4.0) - 2.0;
  p.x = mod(p.x, 8.0) - 4.0;

  result = crabMap(p, result.dist);
  
  vec3 p4daiza = p;
  p4daiza += vec3(0.0, 100.65, 0.0);
  p4daiza.yz *= rot(acos(-1.0)/2.0);
  float d = sdHexPrism(p4daiza, vec2(1.2, 100.1));
  if(d < result.dist) {
    result.dist = d;
    result.material = MAT_DAIZA;
  }

  d = sdLetter(p2);
  if(d < result.dist) {
    result.dist = d;
    result.material = MAT_GAMING;
  }
  
  if(floor(mod(time/2.0, 8.0)) == 7.0) result.material = MAT_GAMING;
  
  return result;
}

vec3 getNormal(vec3 p) {
  float d = 0.1;
  return normalize(vec3(
    map(p + vec3(d, 0.0, 0.0)).dist - map(p + vec3(-d, 0.0, 0.0)).dist,
    map(p + vec3(0.0, d, 0.0)).dist - map(p + vec3(0.0, -d, 0.0)).dist,
    map(p + vec3(0.0, 0.0, d)).dist - map(p + vec3(0.0, 0.0, -d)).dist
  ));
}

vec3 diffuse(vec3 n, vec3 l, vec3 col) {
  float diff = clamp(dot(l, n), 0.0, 1.0);
  return vec3(diff) * col;
}

vec3 specular(vec3 n, vec3 l, vec3 v) {
  float NdotL = dot(n, l);
  vec3 r = normalize(2.0 * n * NdotL - l);
  float spec = pow(max(0.0, dot(r, v)), 100.0);
  return vec3(spec);
}

void main() {
  
  vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
  
  float c = sin(p.x * 5.0 + time);
  c += sin((p.y * 10.0 + time)/2.0);
  c += sin((p.x * 2.0 + p.y * 20.0 + time)/2.0);
  c = sin(c * 5.0 + time * 2.0);
  c += cos(p.x*10.0)*sin(p.x*10.0 + time);
  c = cos(c * 3.0 + time * 2.0 + p.y * 20.0);
  
  vec3 cPos = vec3(sin(time / 2.0) * 8.0, 2.5, 0.0);
  vec3 ta = vec3(0.0, 0.0, -10.0);
  vec3 cDir = normalize(ta - cPos);
  vec3 cSide = cross(cDir, vec3(0.0, 1.0, 0.0));
  vec3 cUp = cross(cSide, cDir);
  float targetDepth = 1.0;
  
  vec3 ray = normalize(cSide * p.x + cUp * p.y + cDir * targetDepth);
  
  float distance = 0.0;
  float rLen = 0.0;
  vec3 rPos = cPos;
  
  vec3 lightDir = -cDir;
  
  vec3 color = vec3(0.0);
  float alpha = 0.0;
  MarchResult marchResult;
  
  for(int i = 0; i < 70; i++) {
    marchResult = map(rPos);
    distance = marchResult.dist;
    rLen += distance;
    
    if(abs(marchResult.dist) < 0.001) {
      
      vec3 normal = getNormal(rPos);

      alpha = 1.0;

      if(marchResult.material == MAT_BODY) {
        vec3 diff = diffuse(normal, lightDir, vec3(1.0, 0.0, 0.0));
        vec3 spec = specular(normal, lightDir, -cDir);
        color = (diff + spec);
      } else if(marchResult.material == MAT_MOUTH) {
        color = diffuse(normal, lightDir, vec3(0.2, 0.2, 0.2));
      } else if(marchResult.material == MAT_GAMING) {
        color = diffuse(normal, lightDir, hsv2rgb(time, 1.0 ,1.0));
      } else if(marchResult.material == MAT_DAIZA) {
        color = diffuse(normal, lightDir, vec3(0.2, 0.1, 0.0));
      } else {
        color = diffuse(normal, lightDir, vec3(1.0));
      }

      break;
    }
    
    rPos = cPos + ray * rLen;
    
  }

  alpha = exp(rLen * -0.095);

  vec3 noise = mix(vec3(0.6, 0.1, 0.95), vec3(0.8, 0.9, 0.0), c) * 0.85;

  color = mix(color, noise, step(alpha, 0.001));
  
  gl_FragColor = vec4(color, 1.0);
}