← All studies MVS Solves  /  Study 02  /  DESCENT
Depth 00.0u / 34.0u
Study 02 — scroll-driven

DESCENT

METHODSigned distance field

An infinite corridor folded out of one repeated shape. Scroll position is normalised to 0–1 and handed to the fragment shader as a uniform — there is no footage here, and scrubbing backwards costs exactly what scrubbing forwards costs.

COST1 shape, ∞ length
Scroll to descend ↓
01 / Origin

The camera is your scrollbar.

Nothing here is a video. You are moving a ray origin through a distance field. Every frame re-solves the whole corridor from scratch at whatever depth you happen to be at.

02 / Clock

One clock, not three.

Lenis drives smooth scroll, the render loop reads the same frame, and the shader reads the same value. No competing rAF loops — that is the difference between scroll-linked 3D that feels attached and 3D that feels towed.

03 / Fold

Infinite for the price of one.

The ribs are a single box folded with a modulo on z. Thirty-four units of corridor cost the same as one, and the open gaps between ribs are what give it a dark vanishing point instead of grey soup.

04 / Fail-safe

And it degrades.

No WebGL2, or reduced motion enabled, and the canvas is dropped for a static field. Every word on this page still reads. The scroll rail and depth counter keep working without a GPU at all.

05 / Exit

Surface.

Three more studies at the index — INK, kinetic type, and spring particles.

MVS Solves — WebGL & motion ↗

Study 02 — scroll-driven

The corridor needs a scrollbar.

Thirty-four units of raymarched corridor folded from a single shape, with your scroll position wired straight into the fragment shader as the camera. A phone has no scrollbar to hand it and no fill-rate to spare.

Below is how it is built.

Best on a desktop — bring a scrollbar ↗
Engineering note

Thirty-four units of corridor for the price of one

The constraint

A corridor you can scrub in both directions at any speed, with no loading, no seeking, and no file to download. It also has to survive a visitor who drags the scrollbar from top to bottom in one motion.

Why the obvious route fails

The usual approach is a pre-rendered image sequence or a scrubbed video. That means megabytes over the wire, decode stalls when scrubbing backwards, and a resolution baked in at export time that will be wrong on half the devices that load it.

What I did instead

The corridor is a signed-distance field with one rib, folded infinitely by a mod() on the z axis. Scroll is normalised to 0–1 and handed to the fragment shader as a uniform. Scrubbing backwards costs exactly what scrubbing forwards costs, because there is nothing to seek — the frame is solved from scratch every time.

The trade-off I accepted

Raymarching is fill-rate bound, so cost scales with pixels rather than with scene complexity. That is the wrong trade for a detailed environment and the right one here, where the geometry is three shapes. An adaptive resolution governor absorbs the rest.

Geometry
1 rib + 1 spine, folded by mod()
March
86 steps max, 0.88 step factor
Corridor length
34 units — O(1) cost
Scroll coupling
One clock; camera eases, input does not
Resolution
Adaptive, 0.6–1.0x on measured frame time
Degradation
No WebGL2 → static field, all copy intact