Liquid Glass Orbs
Smooth-min merged spheres with simulated environment mapping for a glassy, refractive look.
60 FPS • WebGPU
WGSL Shader Source
struct Uniforms { resolution: vec2f, time: f32, padding: f32, mouse: vec2f, blend: f32, }
@group(0) @binding(0) var<uniform> u: Uniforms;
@vertex
fn vs_main(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4f {
let pos = array(vec2f(-1.0,-1.0), vec2f(3.0,-1.0), vec2f(-1.0,3.0));
return vec4f(pos[vi], 0.0, 1.0);
}
fn smin(a: f32, b: f32, k: f32) -> f32 {
let h = clamp(0.5 + 0.5*(b-a)/k, 0.0, 1.0);
return mix(b, a, h) - k*h*(1.0-h);
}
fn map(p: vec3f) -> f32 {
let t = u.time * 0.5;
let p1 = vec3f(sin(t*1.1)*1.5, cos(t*1.3)*1.5, sin(t*1.5)*1.5);
let p2 = vec3f(cos(t*1.2)*1.5, sin(t*1.4)*1.5, cos(t*1.6)*1.5);
let d1 = length(p - p1) - 1.0;
let d2 = length(p - p2) - 1.0;
let d3 = length(p) - 1.2;
return smin(smin(d1, d2, u.blend), d3, u.blend);
}
fn getNormal(p: vec3f) -> vec3f {
let e = vec2f(0.01, 0.0);
return normalize(vec3f(
map(p+e.xyy) - map(p-e.xyy),
map(p+e.yxy) - map(p-e.yxy),
map(p+e.yyx) - map(p-e.yyx)
));
}
@fragment
fn fs_main(@builtin(position) fragCoord: vec4f) -> @location(0) vec4f {
let uv = (fragCoord.xy - 0.5*u.resolution) / u.resolution.y;
var ro = vec3f(0.0, 0.0, -5.0);
var rd = normalize(vec3f(uv, 1.0));
let mx = (u.mouse.x - 0.5) * 6.28;
let my = (u.mouse.y - 0.5) * 6.28;
// simple camera rot
let cx = cos(mx); let sx = sin(mx);
let cy = cos(my); let sy = sin(my);
rd = vec3f(rd.x*cx - rd.z*sx, rd.y, rd.x*sx + rd.z*cx);
ro = vec3f(ro.x*cx - ro.z*sx, ro.y, ro.x*sx + ro.z*cx);
var t = 0.0;
var i = 0;
for(i=0; i<80; i++) {
let p = ro + rd * t;
let d = map(p);
if(d < 0.001 || t > 20.0) { break; }
t += d;
}
var col = vec3f(0.0);
if(t < 20.0) {
let p = ro + rd * t;
let n = getNormal(p);
let r = reflect(rd, n);
// fake environment map
let env = vec3f(0.5) + 0.5 * cos(r.xyx * 5.0 + u.time);
let fresnel = pow(1.0 - max(dot(n, -rd), 0.0), 3.0);
col = mix(vec3f(0.1, 0.3, 0.5), env, fresnel * 0.8 + 0.2);
}
return vec4f(col, 1.0);
} Properties
#webgpu#raymarching#glass#smin
Author: Math Art Core Target: 60 FPS