Hacker News new | ask | show | jobs
Show HN: Ray-color, color palettes sampled off a raytraced tennis ball (meodai.github.io)
1 points by meodai 3 days ago
Years ago I had a Philips Hue setup and a tennis ball lying on the table. Every time the room lights changed, the ball turned into a completely new palette: a red key light here, a cold fill there, a bit of warm bounce off the tabletop. Same ball, new colors, and they always fit together, because they were all made of the same light in the same room.

That observation became a scrappy raytracer prototype that sat on my disk for years. It worked, barely, and every change broke two other things, so I mostly left it alone.

What finally got it over the line was working on it with AI. Not "the AI wrote it": the idea, the model of the room, and the color decisions are mine. But pair-programming with an agent turned the parts I'd been dreading (porting to TypeScript, a WebGL2 preview that falls back to the exact CPU render, a proper web component, nailing down the determinism guarantees) into afternoons instead of months. For the first time the project was actually fun to tinker with, so I did, a lot.

The result: one sphere in a five-sided room, up to three colored lights. Instead of picking colors from a wheel, you place lights and sample points off the sphere's surface. Click it, or drag a line or circle across it and sample N points along the shape. The palette stays coherent for the same reason the tennis ball's did: every color is the same world seen from a different angle. Mirror walls act as virtual light sources, which is the tabletop bouncing warm light back onto the ball.

The API is deliberately scoped to exactly that: one sphere, lights, and simple sample shapes. It's all I needed for generating palettes, and building a direct-manipulation UI for even this small world (draggable lights, shapes that roll onto the back of the sphere like a trackball) was already plenty of complexity.

The library is ~6 kB gzipped, zero dependencies, DOM-free, and deterministic: same scene, same colors, and a sampled color matches its rendered pixel bit-for-bit (all shading in linear RGB, sRGB only at the 8-bit boundary).

Playground: https://meodai.github.io/ray-color/

code: https://github.com/meodai/ray-color

Happy to answer anything about the shading model, the sampling API, or what it was like dragging a years-old prototype into shape with an agent.