Light
Playing
Through.
Gobo-style dappled light (or komorebi 木漏れ日, if you prefer) composited over DOM content. Compare image-based CSS techniques with a multipass reconstruction of Unicorn Studio’s shadow shader.
The compositing model
A mix-blend-mode: multiply layer sits above DOM content. White areas become effectively transparent — the underlying content shows through. Grey areas darken the surface. The effect is a monochromatic light-and-shadow mask, not a coloured filter. The feel: sunlight filtering through foliage.
Light-mode override
Dappled light reads best on warm light-to-mid-tone surfaces, so this page overrides the site-wide dark theme. A warm parchment base lets the shadow pattern feel natural rather than synthetic. On pure white, the shadows are crispest but can feel a little stark.
Four approaches, one light field
Shadow projection gives each panel its own ::after pseudo-element with background-attachment: fixed. All panels reference the same gobo texture locked to viewport coordinates — a coherent light field that drifts across everything.
Gobo element places a single position: fixed div above the page. Full animation freedom, but flat — no per-element depth.
Shader replaces the texture with a procedural reconstruction of the Unicorn effect stack: a vignette is warped by Sine and Voronoi “Shatter” UV distortions, then softened by a 40-sample Bokeh blur. It is also a flat layer, but it can evolve organically without an image or video asset.
Gobo particles runs the same Sine, Shatter, and Bokeh stages as the shader approach, but replaces its initial Vignette with soft sources seeded from the photographic gobo’s bright areas. The gobo itself is never drawn or used to clip the finished forms, so their blurred edges remain intact. Toggle between all four with the controls below.
The gobo texture
The shadow pattern comes from a single photographic gobo image provided to us by Gemini. Simply a WebP of organic branch-and-foliage shapes. Desaturated, contrast-pushed, and slightly brightened before compositing. The grain and natural edge softness are already in the texture; no additional blur pass is needed.
The transform constraint
The shadow-projection approach cannot use CSS transform on the ::after pseudo-elements — it pulls them into a new compositing layer, breaking background-attachment: fixed alignment and destroying the shared light field. Panels would drift out of sync.
Animation without transforms
Since transforms are off-limits, animation happens through background-position keyframe drift (moves the gobo slowly across the viewport) and an opacity pulse (breathes the shadow intensity). Both loop seamlessly with matching start/end keyframes. A separate filter: blur() animation could add extra level of dynamism, but this creates issues around edges as the blur radius changes.
What we learned
The apparent openings are not leaf or capsule primitives. They emerge by feeding a soft, off-centre vignette through two UV distortions: Sine creates the broad wavy bands, and Voronoi “Shatter” breaks them into irregular patches. A downsampled Bokeh pass supplies the final optical softness.
The video gobo
A video gobo source is available but not enabled by default — the <video> element already sits in the gobo container ready to swap in. An MP4 of drifting shadows would animate organically without any CSS keyframes at all, at the cost of a larger asset. The image-based approach with keyframe drift gives comparable results for kilobytes.