💀 💀 💀
Log in to post a comment.
precision highp float; uniform float iTime; uniform vec2 iResolution; uniform float rX;// value=0, min=-4, max=4, step=0.001 uniform float rY;// value=0, min=-4, max=4, step=0.001 uniform float rZ;// value=0, min=-4, max=4, step=0.001 uniform float bgType;// value=1, min=0, max=3, step=1 (Normal, Army of Skulls, Piter Plasma, Spiral) uniform vec3 skin;// value=#FCFCFC uniform vec3 background;// value=#347fcf uniform float eyeDirection;// value=1, min=0, max=3, step=1 (Left, Up, Right, Down) uniform float eyeType;// value=1, min=0, max=3, step=1 (Normal, Gradient, Piter Plasma, Spiral) uniform vec3 eyeColor00;// value=#cd202c uniform vec3 eyeColor01;// value=#cd202c uniform vec3 eyeColor10;// value=#cd202c uniform vec3 eyeColor11;// value=#cd202c uniform float eyeY;// value=2, min=1, max=3, step=1 uniform float eyeHeight;// value=2, min=0, max=6, step=1 uniform float mouthType;// value=1, min=0, max=1, step=1 (One, Three) uniform float mouthY;// value=9, min=4, max=10, step=1 uniform float mouthSize;// value=1, min=0, max=3, step=1 uniform float mouthWidth;// value=3, min=3, max=5, step=2 uniform float sideCheeksWidth;// value=2, min=1, max=10, step=1 uniform float sideCheeksHeight;// value=4, min=1, max=10, step=1 #define AA 2 #define PI 3.1415 #define m3 mat3(-0.7373, 0.4562, 0.4980, 0, -0.7373, 0.6754, 0.6754, 0.4980, 0.5437) #define BLACK vec3(0) const vec3 lightCol = vec3(1.3, 1., .8); const vec3 skyCol = vec3( .4, .6,1.15); const vec3 lightDir = normalize(vec3(-0.25, 0.4, -0.6)); vec2 eyeCoord; mat3 rot; // // Hash functions by Dave Hoskins: // // https://www.shadertoy.com/view/4djSRW // float hash12(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * 443.8975); p3 += dot(p3, p3.yzx + 19.19); return fract((p3.x + p3.y) * p3.z); } vec3 hash33(vec3 p3) { p3 = fract(p3 * vec3(443.897, 441.423, 437.195)); p3 += dot(p3, p3.yxz + 19.19); return fract((p3.xxy + p3.yxx)*p3.zyx); } float noise(in vec2 p) { vec2 i = floor(p); vec2 f = fract(p); vec2 u = f*f*(3. -2.*f); return mix(mix(hash12(i + vec2(0, 0)), hash12(i + vec2(1, 0)), u.x), mix(hash12(i + vec2(0, 1)), hash12(i + vec2(1, 1)), u.x), u.y); } // // rotation matrices // mat2 rot2D(float a) { return mat2(cos(a), sin(a), -sin(a), cos(a)); } mat3 rotX(float a) { return mat3( vec3(1, 0, 0), vec3(0, cos(a), -sin(a)), vec3(0, sin(a), cos(a)) ); } mat3 rotY(float a) { return mat3( vec3(cos(a), 0, sin(a)), vec3(0, 1, 0), vec3(-sin(a), 0, cos(a)) ); } mat3 rotZ(float a) { return mat3( vec3(cos(a), -sin(a), 0), vec3(sin(a), cos(a), 0), vec3(0, 0, 1) ); } // // Background types // vec3 plasma(vec2 pos) { vec3 p = vec3(pos * 2., iTime * 0.05); float a = 1.; vec3 n = vec3(0); for (int i = 0; i <7; i++){ p = m3 * p; vec3 s = sin(p.zxy / a) * a; p += s * 2.; n += s; } return n * 0.25 + 0.5; } vec3 spiral(vec2 uv, vec3 color) { float r = length(uv); float theta = atan(uv.y, uv.x); return fract(theta * (2.5 / PI) + 7.0 * pow(r, 0.4) - iTime) < 0.5 ? color : vec3(0); } vec3 stripes(vec2 uv, vec3 color) { return fract(uv.x * 4. + uv.y * 4. - .2 * iTime) < 0.5 ? color : vec3(0); } // // SDF framework by Inigo Quilez: // // https://www.shadertoy.com/view/Xds3zN // // http://iquilezles.org/www/articles/smin/smin.htm float smin(float a, float b, float k) { float h = max(k-abs(a-b), 0.0)/k; return min(a, b) - h*h*h*k*(1.0/6.0); } // http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm float sdSphere(vec3 p, float s) { return length(p)-s; } 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)); } float sdPlane(vec3 p, vec3 n, float h) { return dot(p, n) + h; } float sdRoundBox(vec3 p, vec3 b, float r) { vec3 q = abs(p) - b + r; return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0) - r; } // http://iquilezles.org/www/articles/smin/smin.htm vec2 opU(vec2 d1, vec2 d2) { return (d1.x<d2.x) ? d1 : d2; } vec2 opS(vec2 d1, vec2 d2) { return (-d1.x>d2.x) ? vec2(-d1.x, d1.y) : d2; } vec2 opI(vec2 d1, vec2 d2) { return (d1.x>d2.x) ? d1 : d2; } vec2 map(in vec3 pos) { if (bgType == 1.) { pos = mod(pos + 25., 50.) - 25.; } pos = rot * pos; pos.y -= sin(iTime) * .5; const float featureDepth = 0.5; const float featureRadius = 0.25; vec3 apos = vec3(abs(pos.x), pos.y, pos.z); // skull vec2 d = vec2(sdRoundBox(pos, vec3(5.5), 1.), 0.); d = opS(vec2(sdBox(apos - vec3(5.5, -5.5, 0), vec3(sideCheeksWidth, sideCheeksHeight, 7.5)), 0.), d); d = opS(vec2(sdBox(pos - vec3(0., -5.5, 5.5), vec3(10., sideCheeksHeight, 6.)), 0.), d); // mouth if (mouthType < .5) { // single block d = opS(vec2(sdRoundBox(apos - vec3(0, 5.5-mouthY-mouthSize+1., -5.5), vec3(mouthWidth * .5, mouthSize+1., featureDepth), featureRadius), 1.), d); } else { // three blocks d = opS(vec2(sdRoundBox(apos - vec3(0, 5.5-mouthY-mouthSize+1., -5.5), vec3(0.5, mouthSize+1., featureDepth), featureRadius), 1.), d); d = opS(vec2(sdRoundBox(apos - vec3(2., 5.5-mouthY-mouthSize+1., -5.5), vec3(0.5, mouthSize+1., featureDepth), featureRadius), 1.), d); } // eyes d = opS(vec2(sdRoundBox(apos - vec3(2., 5.5-eyeY-eyeHeight*.5-.5, -5.5), vec3(1.5, eyeHeight*.5+.5, featureDepth), featureRadius), 2.), d); eyeCoord.y = apos.y - (4.5-eyeY-eyeHeight); eyeCoord.x = mod(pos.x - .5, 4.) * sign(pos.x); return d; } float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax) { float res = 1.0; float t = mint; float ph = 1e10; for (int i=0; i<16; i++) { float h = map(ro + rd*t).x; float y = h*h/(2.0*ph); float d = sqrt(h*h-y*y); res = min(res, 10.0*d/max(0.0, t-y)); ph = h; t += h; if (res<0.0001 || t>tmax) break; } res = clamp(res, 0.0, 1.0); return smoothstep(0., 1., res);// res*res*(3.0-2.0*res); } vec3 calcNormal(in vec3 pos) { vec2 e = vec2(1.0, -1.0)*0.01; return normalize(e.xyy*map(pos + e.xyy).x + e.yyx*map(pos + e.yyx).x + e.yxy*map(pos + e.yxy).x + e.xxx*map(pos + e.xxx).x); } float calcAO(in vec3 pos, in vec3 nor) { float occ = 0.; float sca = 1.; for (int i=0; i<5; i++) { float hr = .005 + .12*float(i)/4.; vec3 aopos = nor * hr + pos; float dd = min(aopos.y, map(aopos).x); occ += -(dd -hr)*sca; sca *= .95; } return clamp(1. - 3.*occ, 0., 1.); } vec3 render(in vec3 ro, in vec3 rd) { float t = 0.; float tmax = 1000.; float mat = -1.; for (int i=0; i<100; i++) { vec2 res = map(ro+rd*t); if (abs(res.x) < max(0.001, .0005*t) || t > tmax) { mat = t > tmax ? -1. : res.y; break; } t += res.x; } // shade scene vec3 bgCol = bgType == 2. ? plasma(rd.xy) : bgType == 3. ? spiral(rd.xy, background) : background; bgCol *= bgCol; vec3 col = bgCol; if (mat >= 0.) { vec3 pos = ro + t*rd; vec3 nor = calcNormal(pos); vec3 ref = reflect(rd, nor); float eyeY = max(0., floor(eyeCoord.y)); float eyeX = max(0., floor(3. - abs(eyeCoord.x))); bool left = eyeCoord.x > 0.; vec3 eye = left ? eyeColor00 : eyeColor10; if (eyeType == 0.) { // normal } else if (eyeType == 1.) { // gradient if (eyeHeight > 0.) { vec3 eye2 = left ? eyeColor01 : eyeColor11; eye = mix(eye2 * eye2, eye * eye, (eyeY / eyeHeight)); eye = sqrt (eye); } } else if (eyeType == 2.) { // plasma eye = plasma(eyeCoord.xy * .1); } else if (eyeType == 3.) { // spiral eye = spiral(abs(eyeCoord) - 1.5, eye); } if (eyeDirection == 0. && eyeX < .5) eye = BLACK; else if (eyeDirection == 1. && eyeY > (eyeHeight - .5)) eye = BLACK; else if (eyeDirection == 2. && eyeX > 1.5) eye = BLACK; else if (eyeDirection == 3. && eyeY < .5) eye = BLACK; col = (mat == 0. ? skin : mat == 1. ? BLACK : eye); col *= col; // lighting // use three lights setup as made popular by Inigo Quilez // sun vec3 hal = normalize(lightDir-rd); float difSun = max(dot(nor, lightDir), 0.); difSun *= calcSoftshadow(pos, lightDir, 0.02, 2.5); float specSun = pow(clamp(dot(nor, hal), 0., 1.), 16.) * difSun; specSun *= 0.04+0.96*pow(clamp(1.0-dot(hal, lightDir), 0., 1.), 5.); vec3 diff = (difSun)*lightCol; vec3 spec = (2.5*specSun)*lightCol; // sky float difSky = sqrt(0.75+0.25*nor.y); float specSky = smoothstep(-0.2, 0.2, ref.y) * difSky; specSky *= 0.04+0.96*pow(clamp(1.0+dot(nor, rd), 0.0, 1.0), 5.0); vec3 skyLight = bgType == 2. ? plasma(ref.xy) : skyCol; diff += (0.3*difSky)*skyLight; spec += specSky*skyLight; // back light / ambient float difBack = max(dot(nor, -lightDir), 0.); diff += col*(0.08*difBack); col = diff * col + spec; // fog col = mix(col, bgCol, clamp(1. - exp(-0.005*t) * 1.1, 0., 1.)); } // cheap gamma correction return sqrt(col); } mat3 setCamera(in vec3 ro, in vec3 ta) { vec3 cw = normalize(ta -ro); vec3 cu = normalize(cross(cw, vec3(0, 1, 0))); vec3 cv = normalize(cross(cu, cw)); return mat3(cu, cv, cw); } void main() { rot = rotZ(rZ) * rotX(rX + .25 * (noise(vec2(1.5, iTime * 0.5)) - .5)) * rotY(rY + .5 * (noise(vec2(2.5, iTime * 0.3)) - .5)); vec3 tot = vec3(0); vec2 q = (gl_FragCoord.xy * 2. - iResolution.xy) / iResolution.y; for (int m=0; m<AA; m++) { for (int n=0; n<AA; n++) { vec2 o = vec2(float(m), float(n))*(2./float(AA)) - .5; // rotate AA offset to reduce aliasing o *= rot2D(0.463647609); vec2 p = q + o/iResolution.y; vec3 ro = vec3(sin(iTime*.3), 0., -22.5); vec3 ta = vec3(0., ro.y, 0.); mat3 ca = setCamera(ro, ta); vec3 rd = ca * normalize(vec3(p.xy, 2)); vec3 col = render(ro, rd); tot += col; } } tot *= (1./float(AA*AA)); // vigneting q = gl_FragCoord.xy / iResolution.xy; tot *= 0.25+0.75*pow(16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y), 0.15); // noise tot += vec3(hash12(gl_FragCoord.xy) * 0.02); gl_FragColor = vec4(tot, 1.); }