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