Files
shaders/4_ice_scene.frag
T
emil28092005 27d238cbe6 Ice slab with layered plasma, two-pass refraction
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.
2026-10-30 19:56:16 +03:00

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