// Pass A: icy scene. RGB = colour, A = linear depth / 8.0 (our z-buffer) precision highp float; uniform vec2 u_res; uniform float u_time; uniform vec2 u_mouse; float sdSphere(vec3 p, float r){ return length(p) - r; } float map(vec3 p){ float d = sdSphere(p, 1.0); for(int i=0;i<3;i++){ float fi = float(i); vec3 q = p; float a = u_time*0.5 + fi*2.1; q.xz = mat2(cos(a),-sin(a),sin(a),cos(a)) * q.xz; d = min(d, sdSphere(q - vec3(0.75,0.0,0.0), 0.34)); } return d; } void main(){ vec2 uv = (gl_FragCoord.xy - 0.5*u_res)/u_res.y; vec3 ro = vec3(0.0,0.0,8.5); vec3 rd = normalize(vec3(uv, -1.6)); float t = 0.0; int hit = 0; for(int i=0;i<90;i++){ float d = map(ro + rd*t); if(d < 0.001){ hit = 1; break; } t += d; if(t > 12.0) break; } vec3 col = vec3(0.008,0.02,0.045); col += 0.07*pow(1.0 - abs(uv.y)*0.9, 4.0)*vec3(0.15,0.35,0.6); // cold haze float depth = 12.0; if(hit == 1){ depth = t; vec3 pos = ro + rd*t; vec3 n = normalize(vec3(map(pos+vec3(0.001,0,0))-map(pos-vec3(0.001,0,0)), map(pos+vec3(0,0.001,0))-map(pos-vec3(0,0.001,0)), map(pos+vec3(0,0,0.001))-map(pos-vec3(0,0,0.001)))); vec3 l = normalize(vec3(0.45,0.85,0.55)); float dif = max(dot(n,l),0.0); float fre = pow(1.0 - max(dot(n,-rd),0.0), 3.0); // frozen layers instead of rainbow float f = 0.5 + 0.5*sin(pos.y*20.0 + u_time*2.0 + pos.x*5.0 + n.z*3.0); vec3 alb = mix(vec3(0.90,0.97,1.00), vec3(0.34,0.66,0.92), f); col = alb*(0.06 + 1.05*dif) + vec3(0.60,0.90,1.0)*fre*1.6; col *= 0.86 + 0.14*sin(pos.y*38.0 + u_time*4.0); } // depth fog: far things fade into the cold void col = mix(col, vec3(0.03,0.10,0.19), smoothstep(3.0, 12.0, depth)*0.85); gl_FragColor = vec4(col, clamp(depth/12.0, 0.0, 1.0)); }