Inspiration

I never had a desk of my own growing up, no dedicated space, no corner that was mine. So I built the one I would've loved to have. The idea is simple: if you don't have something, you build it. I wanted a desk you could actually customize and work at, something that might make someone in the same position think, if we don't have it, why not build it ourselves?

What it does

The Desk is a fully interactive 3D workspace, built to feel lived-in rather than rendered. You can turn on the lamp, type on the keyboard and watch it hit the CRT monitor, flip through a notebook, flip the calendar page, spin the globe, take a polaroid with your webcam and pin it to the corkboard, and switch between day and a warm, golden-hour night mode. There's even real Spotify integration playing through the desk speaker with working play/skip controls. Every object responds to being clicked, not just looked at.

How we built it

Built entirely in Three.js, with hand-drawn canvas textures for the wood grain, corkboard, posters, and fabric, UnrealBloomPass for the glow, and the Web Audio API for a synthesized, positional ambient soundscape. A custom spherical-lerp camera system handles zooming into hotspots and gliding back home, with manual click/double-click/middle-drag gesture disambiguation so interactions don't collide.

Challenges we ran into

Notebook and calendar page-flip physics — pages initially flipped from the wrong hinge and sank underneath the closed book, or on the calendar, halted halfway into an X-shape instead of completing the flip. Got both working with correct axis-specific rotation, stacking order, and resting pose.

Golden-hour lighting — faking sunlight through blinds meant adding shadow-casting slat geometry, but the math initially placed the slats outside the light's shadow frustum entirely, so they cast no shadow at all. Once fixed, the blinds then became a physical obstruction to work around. Getting the light itself right also meant separating "washed out" (too much ambient fill) from "not bright enough" (directional intensity and tone-mapping exposure) — two different bugs that looked like one.

A ReferenceError that broke the whole scene — adding a "click the corkboard to take a photo" feature meant registering an interaction early in the build, but the shared raycastTargets array it depended on wasn't declared until much later in the file. Fixed by moving shared state declarations to the very top of scene setup.

Accomplishments that we're proud of

A genuinely rich, skeuomorphic scene — a dozen+ individually interactive objects (lamp, notebook, calendar, monitor, keyboard, mouse, speaker, globe, clock, corkboard), each with physically-motivated animation rather than generic click handlers. Real, working page-flip physics on two separate objects, each with its own correct hinge axis, stacking order, and resting pose. Actual Spotify integration, not a placeholder — wired up the real iFrame Controller API so the desk speaker plays real requested songs with real controls. A cinematic camera system with smooth hotspot focus and gesture disambiguation across click, double-click, and middle-drag. A believable golden-hour lighting mode — a tuned combination of warm directional light, reduced ambient fill, tone-mapping exposure, and shadow-casting blinds geometry to fake streaked sunlight from a reference photo. A webcam-to-3D-corkboard pipeline — a real photo capture → canvas texture → 3D mesh spawn animation, all coming together cleanly.

What we learned

3D rotation bugs are rarely about the angle — they're about the axis. Almost every "stuck" or "wrong-looking" animation traced back to a sign or axis convention rather than a bad target number. The most robust fix is often the one that doesn't depend on getting the math exactly right. Giving both faces of a page the same texture meant the notebook looked correct regardless of any future rotation-math error — more durable than a precise-but-fragile fix. Working blind changes how you debug. Screenshots turned out to be essential — several "fixes" that looked reasonable on paper were only diagnosably wrong once actually rendered. That shifted the approach toward smaller, more verifiable changes. Declaration order matters more in a single growing script than it seems. The raycastTargets crash was a reminder to check where shared state is declared relative to where it's used, not just whether a new feature itself is correct. "Looks washed out" and "not bright enough" are different bugs with different fixes — treating "lighting feels wrong" as one problem instead of three led nowhere at first.

What's next for The Desk

I'd want anyone to be able to build their own desk for themselves — an actually functional workspace, not just a showcase. Click a book on the shelf, and it opens a real PDF you've uploaded. Open the monitor, and it's your actual desktop. Personalized Spotify playlists, customizable drinks, electronics, and decor. A notebook that opens into a real, functioning writing surface. Walls you can decorate however you like, and a corkboard you can fill with your own memories.

Built With

Share this project:

Updates

Submission history