fresnel_shader
The shader-based Liquid Glass fallback for
fresnel.
Apps should not depend on this package directly. Depend on fresnel, which
uses this automatically on every platform without native glass: Android, web,
Windows, Linux, and iOS below 26.
What it does
Pure Dart, no native code, so it runs anywhere Flutter does.
ShaderGlassSurface renders fresnel_glass.frag as an ImageFilter.shader
over the backdrop, composed on top of a hardware gaussian:
ui.ImageFilter.compose(
outer: ui.ImageFilter.shader(shader),
inner: ui.ImageFilter.blur(sigmaX: sigma, sigmaY: sigma),
)
Blurring in the filter chain rather than inside the shader matters — Flutter's blur is a tuned separable pass, and a hand-written multi-tap loop is both slower and worse. The shader is left to do only what the built-in filters cannot:
- Edge refraction. A signed-distance field gives a surface normal; samples bend along it, strongest at the rim. This lensing is what separates glass from a frosted pane.
- Specular rim. Directional highlight with an ambient floor so the rim stays legible on dark backgrounds.
- Thickness falloff, so the surface reads as a slab rather than a decal.
- System intensity. The whole effect scales toward "off" with the user's glass-intensity preference, so hand-rendered glass tracks the OS instead of drifting away from it.
FallbackGlassSurface is the last resort — a plain BackdropFilter with a tint
and hairline rim, used on Skia and web where backdrop shaders are unavailable,
and whenever the shader fails to compile.
Precision
The shader declares precision highp float. mediump's 10-bit mantissa
quantises the displacement into roughly 1.5px of visible banding at typical
thickness values on mobile GPUs.
Notes for anyone writing their own
Flutter's .frag dialect is GLSL, not SkSL: uniform sampler2D and
texture(sampler, uv) with normalised coordinates. uniform shader and
.eval() are SkSL and fail impellerc with a bare syntax error.
Size a glass surface from inside a Positioned.fill, not from an outer
LayoutBuilder. LayoutBuilder reports the constraints handed down, so any
unbounded parent — a Row, Column, or scrollable — yields infinity and
silently disables the effect.
License
MIT
Libraries
- fresnel_shader
- Shader-based Liquid Glass fallback for
fresnel.