/* Hyper Tunnel from "Sailing Beyond" (demoscene producion) https://www.youtube.com/watch?v=oITx9xMrAcM& https://www.pouet.net/prod.php?which=77899 */ /* http://bit.ly/shadertoy-plugin */ #pragma optimize(off) #define getNormal getNormalHex #define FAR 1e3 #define INFINITY 1e32 #define T iTime #define mt (iChannelTime[0] > 0. ? iChannelTime[0] : iTime) #define FOV 70.0 #define FOG .06 #define PI 3.14159265 #define TAU (2*PI) #define PHI (1.618033988749895) float vol = 0.; float hash12(vec2 p) { float h = dot(p,vec2(127.1,311.7)); return fract(sin(h)*43758.5453123); } // 3d noise float noise_3(in vec3 p) { vec3 i = floor(p); vec3 f = fract(p); vec3 u = 1.-(--f)*f*f*f*-f; vec2 ii = i.xy + i.z * vec2(5.0); float a = hash12( ii + vec2(0.0,0.0) ); float b = hash12( ii + vec2(1.0,0.0) ); float c = hash12( ii + vec2(0.0,1.0) ); float d = hash12( ii + vec2(1.0,1.0) ); float v1 = mix(mix(a,b,u.x), mix(c,d,u.x), u.y); ii += vec2(5.0); a = hash12( ii + vec2(0.0,0.0) ); b = hash12( ii + vec2(1.0,0.0) ); c = hash12( ii + vec2(0.0,1.0) ); d = hash12( ii + vec2(1.0,1.0) ); float v2 = mix(mix(a,b,u.x), mix(c,d,u.x), u.y); return max(mix(v1,v2,u.z),0.); } float fbm(vec3 x) { float r = 0.0; float w = 1.0, s = 1.0; for (int i=0; i<4; i++) { w *= 0.25; s *= 3.; r += w * noise_3(s * x); } return r; } float yC(float x) { return cos(x * -.134) * 1. * sin(x * .13) * 15.+ fbm(vec3(x * .1, 0., 0.) * 55.4); } void pR(inout vec2 p, float a) { p = cos(a)*p + sin(a)*vec2(p.y, -p.x); } struct geometry { float dist; vec3 hit; int iterations; }; // Cylinder with infinite height float fCylinderInf(vec3 p, float r) { return length(p.xz) - r; } geometry map(vec3 p) { p.x -= yC(p.y * .1) * 3.; p.z += yC(p.y * .01) * 4.; float n = pow(abs(fbm(p * .06 )) * 12., 1.3); float s = fbm(p * 0.01 + vec3(0., T * 0.14, 0.)) * 128.; geometry obj; obj.dist = max(0., -fCylinderInf(p, s + 18. -n)); p.x -= sin(p.y * .02) * 34. + cos(p.z * 0.01) * 62.; obj.dist = max(obj.dist, -fCylinderInf(p, s + 28. + n * 2.)); return obj; } float t_min = 10.0; float t_max = FAR; const int MAX_ITERATIONS = 100; geometry trace(vec3 o, vec3 d) { float omega = 1.3; float t = t_min; float candidate_error = INFINITY; float candidate_t = t_min; float previousRadius = 0.; float stepLength = 0.; float pixelRadius = 1./ 1000.; geometry mp = map(o); float functionSign = mp.dist < 0. ? -1. : +1.; float minDist = FAR; for (int i = 0; i < MAX_ITERATIONS; ++i) { mp = map(d * t + o); mp.iterations = i; float signedRadius = functionSign * mp.dist; float radius = abs(signedRadius); bool sorFail = omega > 1. && (radius + previousRadius) < stepLength; if (sorFail) { stepLength -= omega * stepLength; omega = 1.; } else { stepLength = signedRadius * omega; } previousRadius = radius; float error = radius / t; if (!sorFail && error < candidate_error) { candidate_t = t; candidate_error = error; } if (!sorFail && error < pixelRadius || t > t_max) break; t += stepLength * .5; // ;( } mp.dist = candidate_t; if ( (t > t_max || candidate_error > pixelRadius) ) mp.dist = INFINITY; return mp; } void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 ouv = fragCoord.xy / iResolution.xy; vec2 uv = ouv - .5; uv *= tan(radians (FOV) / 2.0) * 4.; vec3 vuv = normalize(vec3(cos(T), sin(T * .11), sin(T * .41))), // up ro = vec3(0., 30. + iTime * 100., -.1); ro.x += yC(ro.y * .1) * 3.; ro.z -= yC(ro.y * .01) * 4.; vec3 vrp = vec3(0., 50. + iTime * 100., 2.); vrp.x += yC(vrp.y * .1) * 3.; vrp.z -= yC(vrp.y * .01) * 4.; vec3 vpn = normalize(vrp - ro), u = normalize(cross(vuv, vpn)), v = cross(vpn, u), vcv = (ro + vpn), scrCoord = (vcv + uv.x * u * iResolution.x/iResolution.y + uv.y * v), rd = normalize(scrCoord - ro), oro = ro; vec3 sceneColor = vec3(0.); geometry tr = trace(ro, rd); tr.hit = ro + rd * tr.dist; vec3 col = vec3(1., 0.5, .4) * fbm(tr.hit.xzy * .01) * 20.; col.b *= fbm(tr.hit * .01) * 10.; sceneColor += min(.8, float(tr.iterations) / 90.) * col + col * .03; sceneColor *= 1. + .9 * (abs(fbm(tr.hit * .002 + 3.) * 10.) * (fbm(vec3(0.,0.,iTime * .05) * 2.)) * 1.); sceneColor = pow(sceneColor, vec3(1.)) * (iChannelTime[0] > 0. ? texelFetch(iChannel0, ivec2(128, 0), 0).r * min(1., mt * .1) : 0.6); vec3 steamColor1 = vec3(.0, .4, .5); vec3 rro = oro; ro = tr.hit; float distC = tr.dist, f = 0., st = .9; for (float i = 0.; i < 24.; i++) { rro = ro - rd * distC; f += fbm(rro * vec3(.1, .1, .1) * .3) * .1; distC -= 3.; if (distC < 3.) break; } steamColor1 *= iChannelTime[0] > 0. ? texelFetch(iChannel0, ivec2(32, 0), 0).r : 1.; sceneColor += steamColor1 * pow(abs(f * 1.5), 3.) * 4.; fragColor = vec4(clamp(sceneColor * (1. - length(uv) / 2.), 0.0, 1.0), 1.0); fragColor = pow(abs(fragColor / tr.dist * 130.), vec4(.8)); }