How Fluid Glass Pulls Off True 3D Refraction in the Browser
SVG-filter glass looks cheap — jagged edges, wrong colors, no real depth. This approach gives WebGL UIs a physically accurate refractive material that works on arbitrary HTML-backed content, not just pre-rendered images, and the single-FBO technique keeps it to one render pass instead of the four-pass pipelines common in shader art.
The Fluid Glass component from React Bits renders a physically plausible glass lens, cube, or navigation bar that refracts whatever sits behind it — text, images, a full scroll gallery — in real time. Instead of faking the effect with SVG displacement maps or post-processing blurs, it isolates the background into a separate Three.js scene, renders that scene to an FBO every frame, then feeds the resulting texture into MeshTransmissionMaterial on a 3D mesh. The shader offsets texture lookups based on surface normals, index of refraction, thickness, and separate RGB channel dispersion.
Three modes ship out of the box: a cylindrical lens that follows the pointer, a multi-face cube, and a bottom-locked bar for frosted-glass nav. All models are preloaded as GLB files to avoid flicker on mode switch. Pointer tracking bypasses R3F’s event system and computes NDC coordinates directly from the canvas bounding rect, because ScrollControls hijacks standard pointer events.
A full-page scroll gallery sits behind the glass, with zoom driven by Drei’s useScroll ranges. Typography and nav items adapt font sizes and spacing across mobile, tablet, and desktop breakpoints via a resize listener. The entire pipeline runs in a single Canvas with a narrow 15° FOV camera at Z=20, placing the glass at Z=15 so it sits optically between the viewer and the background plane.
The single-FBO approach is notably lean compared to the four-pass offscreen pipelines used in shader-art glass editors; it sacrifices multi-bounce realism for runtime performance that fits inside a scroll-driven page.
Baking the entire background scene to a texture every frame means the glass refracts live DOM-backed content (text, scroll galleries) rather than static images — this is the key difference from the liquid-glass-studio project, which only works on pre-rendered pictures.
Bypassing R3F’s pointer system and computing NDC manually is a practical workaround for a common pain point: Drei’s ScrollControls hijacks events, so any interactive 3D object inside a scroll scene needs its own raw DOM event listener.
The adaptive scaling logic — measuring the GLB bounding box and fitting it to 90% of the viewport width at the glass depth plane — is a reusable pattern for any 3D UI component that needs to size itself correctly across viewports without hardcoded scale values.