Real-time glass refraction
for UI surfaces.

Glacias is a WebGL2 engine I built on my own in March 2026. It uses each pixel's distance from a shape's edge to control distortion, blur, and color fringing. Built-in shapes and custom SVG paths go through the same shader.

CSS backdrop-filter: blur() blurs a surface without accounting for its shape. I wanted distortion concentrated around a curved boundary, with a quieter interior and color fringing at the edges.

Try it

Glass effect controls

Move your pointer or drag on the canvas to position the lens. Use the controls to change its shape and refraction.

Shape

How the shader works

The engine draws a fullscreen quad and does all of its work in a single GLSL fragment shader pass. For each pixel it computes the signed distance to the shape boundary (negative inside, positive outside) and derives the surface normal from the gradient of that distance, so one field defines the outline and also steers the distortion.

Pushing pixels straight out from the center makes a shape look pinched. I rotate the displacement 90° from the normal so it runs along the nearest edge, which reads as light bending through curved glass. A falloff curve scales the effect from full strength at the boundary to zero at the center. Its exponent sets how steep that drop is, from a gentle spread into the interior to a narrow band at the edge, and the Falloff slider in the demo above adjusts it.

The red, green, and blue channels are sampled at slightly different distances along the same displacement, which produces the color fringing at the edge. The blur averages 16 samples in a ring around each point and is scaled by the same falloff, so the interior stays clearer than the edge. An optional tint is blended in last, after refraction and blur, which lets it color the glass without changing the distortion.

The core is plain TypeScript and WebGL2, with no Three.js, no post-processing library, and no build-time shader compilation. React is an optional peer dependency, used only by a thin wrapper component. Before it starts, the engine checks for a reduced-motion preference, WebGL2 support, and low-end hardware (two or fewer logical cores). If any check fails, the surface falls back to a CSS backdrop blur, or to a plain translucent fill on low-end devices, and the demo explains why the interactive version is unavailable.

Custom SVG shapes

Besides the five built-in shapes (circle, rounded rectangle, hexagon, flower, and star), Glacias accepts any closed SVG path and converts it to a distance field texture at runtime. The conversion uses the Felzenszwalb–Huttenlocher distance transform, an O(n) algorithm that computes exact Euclidean distances for every pixel in the texture.

The texture is uploaded to the GPU, where the shader reads distance from it and derives normals by central differences. Any closed path, such as a cloud or a text outline, then gets the same refraction as the built-in shapes.

I used this path conversion for cloud-shaped project labels in an earlier version of the portfolio.