Pass 1 renders eight plasma sheets into an atlas with linear depth in alpha; pass 2 marches the refracted ray to each sheet and absorbs it by real path length, so near and far layers separate under pointer parallax. Plasma cycle repeats exactly every 30 s; - / = change speed.
57 lines
1.8 KiB
GLSL
57 lines
1.8 KiB
GLSL
// 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));
|
|
}
|