MONO CHROME
A 1-bit interface layer for products that refuse to blend in. Ordered dithering on the GPU, inertial scroll, aggressive motion — two colours, infinite signal.
We deleted 16,777,214 colours. What remained was the interface.
Noise is a design failure.
Every gradient, every shadow, every 8-bit gradient band is a decision you delegated to a renderer. We took the decision back. One threshold, evaluated per pixel, per frame.
FILE: /core/dither.tsl · 512 BYTESconst cell = px.mod(vec2(8)).floor();
const th = texture(bayer, cell).r;
const lum = dot(rgb, LUMA);
return vec4(vec3(step(th, lum)), 1.0);
GPU dithering, zero post-stack.
Ordered 8×8 Bayer evaluated per fragment inside the node graph. Every frame is quantised to pure black and pure white before it reaches the display.
60 FPS TARGET · 0 MS CPU READBACKAggressive. Never abrupt.
Scroll-linked timelines with frame-perfect easing curves. Motion that hits hard on entry and settles like it was always there.
SCROLLTRIGGER · SCRUB 1.0 · EXPO.OUTOne breath, top to bottom.
Inertial smooth scrolling that never fights the browser and never fights the timeline. Damped, synced, predictable.
LERP 0.1 · SYNCED TO GSAP TICKERDirect the scene, don't code it.
Animation state authored on a timeline, then driven from a single scroll value. One source of truth for every moving part.
STATE → UNIFORM → FRAMEA million triangles, no loader.
Production geometry streamed and decoded at runtime. The heavy stuff never touches the critical path.
RUNTIME DECODE · 0 BLOCKING BYTESReady to go mono?
Take the layer and ship something people remember. Two colours is all you need.
Get the layer- Full dither node source
- Single commercial project
- Community support
- MIT-ish, honestly
- Everything in PIXEL
- Unlimited commercial projects
- Motion & scroll timeline presets
- Theatre state files
- Priority render support
- Everything in DITHER
- White-label & redistribution
- Bespoke shader work
- Named engineer on Slack