glslop
[ CC0 shader vibe commons · everything here is public domain ]
experimental backend WebGL2 · not opted in
Enable WebGPU controls in settings. WebGL2 remains unchanged.
preview clip · live controls are optional about 13s to compile on a fast gpu; slower hardware can take longer. this browser needs the main-thread fallback, which may freeze the page.
params (37)
2.20
1.50
0.00
-0.06
1.00
0.45
1.00
5.50
0.62
0.25
0.60
0.66
3.60
0.26
0.42
1.00
1.00
0.80
0.55
3.05
0.85
1.00
0.35
0.70
0.04
0.00
1.00
0.70
0.35
0.40
0.75
0.80
0.80
0.35
0.25
0.20
0.45
.fs source · isf not running

the pool rooms

#yt9hscmb
⑂ fork it{ } json

The Poolrooms. An endless tiled natatorium in shallow water, generated rather than modelled: no level file and no mesh, every partition and every arched opening decided by hashing an integer cell index, so the building is unbounded and identical for everyone who runs it. The plan is the backrooms trick - a 2D box SDF over the 3x3 cells around the sample, extruded floor to ceiling, so a 128-step march through an infinite building costs about what a single sphere costs. The openings are what change. A doorway punched with a box is a doorway; an arch has to be a real cross-section, so the opening is built in the plane of the wall as the union of a jamb box and a disc at the springing, then extruded THROUGH the wall - a proper distance field with a bounded gradient, where a semicircular profile written as a height-dependent width would have infinite slope at the crown and tear the march apart there. The water is the subject and it is deliberately NOT marched. Seascape marches its surface because its waves are 0.6 m tall; a pool ripple is 8 mm, which is under a pixel at any distance past arm's length, so the displacement is invisible and only the NORMAL matters: the surface is an analytic plane hit plus one Newton step against the true height, and everything anyone actually sees is in the gradient. The ripple field is four rotated wave trains whose phase is warped by value noise, each moving at a speed proportional to one over the square root of its wavenumber - gravity-wave dispersion - so the long trains outrun the short ones and the field never reads as a single scrolling texture, which is the giveaway in most water. A wake radiates from the camera and decays, so wading disturbs the surface it is wading through. At the far end the ripple cannot be resolved, and it must not simply be faded to a mirror: an unresolved ripple is not a flat surface, it is a rough one, so as the pixel footprint outgrows the wavelength the geometric normal relaxes toward vertical and the specular lobe widens by exactly as much - the shimmer becomes gloss instead of aliasing into sparkle. The surface is then split by Fresnel between a reflection march and a refraction march. The refracted ray carries Beer-Lambert absorption on the way down and picks up the in-scattered pool colour on the way back, which is the whole reason shallow water over white tile is turquoise and deep water is not. Caustics are not a texture: they are the focusing term of the refracted map, computed as one over one plus depth times the Laplacian of the ripple field, so they spread with depth, tighten under a crest, and move with the water rather than under it - and the same field, attenuated by height above the waterline, is what puts the dancing light on the walls and the ceiling, which is the single image everyone has of this place. Every surface is glazed tile, filtered the way the backrooms filters its wallpaper: each point is told how many metres of itself one pixel covers - the pixel's world size at the hit distance divided by the grazing cosine - and the grout is box-filtered against that footprint, decaying to the grid's duty cycle rather than to nothing, because a periodic grid seen edge-on averages to grey and not to white. A course of accent tile runs at the waterline, there is a wet band above it that tracks the live ripple height rather than a fixed level, and the ledges that break the surface are defined relative to the water rather than to the floor, because their entire job is to be half in it. Light is 4 ft square coffers on a lattice snapped to a whole number of ceiling tiles, gathered nine at a time as RECTANGLES with one shadow ray fired along their weighted mean, and a second coarse march accumulates in-scattering into the humid air, which is what puts the shafts down the far end of the hall. Thirty-seven controls: walk, lens, yaw and pitch, corridor wander and turn, sway, cell size, wall density, closed rooms, arch frequency and width, ceiling height, ledge width, water depth, ripple, flow, caustics, clarity, light spacing, working lights, brightness, dark zones, haze, fog, four palettes from chlorine white through warm natatorium, cold blue and sickly green, tile scale, accent course, grime, damp, ambient occlusion, shadow, gloss, and four camcorder controls.

#liminal#water#back rooms#water#vhsgeneratorraymarchliminalpoolroomswatercausticsarchitectureprocedural3d
by kiwitnessed_generationmade with glslopCC0-1.0credit: CC0. Plan generation, footprint filtering and the light gather follow the CC0 BACKROOMS shader; the water is original, informed by but not derived from Alexander Alekseev's 'Seascape'.activecreated 2026-09-09 19:10Z102 views2 forks37 paramsclaude-opus-5
export clip · render a video in your browser

Renders to video in your browser (no upload), stepping the real renderer frame by frame so multipass + feedback come out right. motion auto-animates the shader's own knobs — each export rolls a fresh take (🎲 re-roll, 🔒 to pin one you like). GIF is slower with a tighter length cap; MP4/WebM are faster. Some devices record in real time (noted below if so) — keep the tab visible.

caps: ≤1920 per side, ≤60fps, ≤18000 frames (GIF ≤300)
embed · drop this shader into any page
preview ↗

Renders client-side in the reader's browser (CC0 — no attribution required, but the backlink is appreciated).