Light torn into its spectrum — a diffraction grating over the frame.
GLSL fragment shader
The effect's own code. The uniforms and helpers above it — uTex, uFeedback, the depth proxy, the frame ring, depthAt(), timeAt() — are the same header every Ether-MOSH shader opens with, and are documented once on the registry rather than reprinted on all 143 pages.
void main(){ vec2 c = vUv - 0.5; c.x *= uResolution.x / max(uResolution.y, 1.0); float r = length(c); vec2 radial = c / max(r, 1e-4); float ang = 0.8 + uTime * 0.15; vec2 linear = vec2(cos(ang), sin(ang)); // Bend morphs a straight diffraction grating into a radial prism halo. // A plain rotation angle would be a dead axis: 0 and 2PI are the same // direction, so a full drag would land exactly where it started. vec2 dir = normalize(mix(linear, radial, uBend) + vec2(1e-5)); float reach = 0.004 + uSpread * mix(0.05, 0.05 + r * 0.13, uBend); // A grating does not smear the image, it copies it: a sharp zero order // straight through, plus dimmer spectral ghosts either side. Averaging the // taps instead (the old approach) converged to a coloured blur, which // measured as a near-duplicate of Zoom Blur. Keeping the zero order sharp // is what makes this read as a prism and keeps the detail HDR-crisp. vec3 base = texture2D(uTex, vUv).rgb; vec3 ghost = vec3(0.0); vec3 wsum = vec3(1e-3); // Seven spectral orders, violet through red, each displaced by its own // "wavelength" — the longer the wavelength, the further it is bent. for (int i = 0; i < 7; i++) { float lam = float(i) / 6.0; vec3 w = hsv2rgb(vec3(0.72 - lam * 0.72, 1.0, 1.0)); float off = mix(0.3, 1.0, lam) * reach; ghost += (texture2D(uTex, vUv + dir * off).rgb + texture2D(uTex, vUv - dir * off).rgb) * w; wsum += w * 2.0; } ghost /= wsum; float gl = dot(ghost, vec3(0.299, 0.587, 0.114)); // Split the ghost into pure colour fringe and its own brightness: the // fringe paints spectral edges everywhere, the brightness term only spills // out of highlights, the way a real prism throws its rainbow off bright // sources rather than washing the whole frame. vec3 chroma = ghost - gl; vec3 col = base + chroma * (0.9 + uSpread * 1.8) + ghost * gl * gl * uSpread * 1.2; // Faint travelling interference fringes sell the grating. float fringe = sin(dot(vUv, dir) * 140.0 - uTime * 1.5) * 0.5 + 0.5; col *= 1.0 + fringe * uSpread * 0.12; gl_FragColor = vec4(col, texture2D(uTex, vUv).a); }