From eye level it is a rose, a valley, a flower box. From straight above, the same geometry resolves into a working code. Not a QR code with a picture behind it, and nothing that transforms on a timer — one object, two readings.
The idea
A QR decoder is far less fussy than it looks. It does not care about hue, it does not care what an element is, and — critically — under orthographic projection it cannot see height at all. Everything it cares about is the average lightness of each module cell as seen from directly above.
That leaves an enormous amount of freedom. The what, the colour, and the height of every element are all free, provided each module’s mean lightness lands in the right band. RealmQR spends that freedom on making a scene.
The three properties it rests on
Height is free. Under an orthographic camera pointing straight down, a vertical face has
zero projected area, and two elements at the same (x, y) but different heights land on
exactly the same pixel. A dot cloud can be sculpted into a flower without changing a single
bit of the code. This is what makes it a drone formation rather than a bumpy floor.
Hue is free. A scanner grayscales the image before it binarises. An element keeps its own colour and only its lightness is pushed into a light or dark band — a leaf stays green, it just becomes a dark green. The code is the scene quantised, not a black square laid over it.
Coverage is the signal. Each module holds a grid of elements, and the module’s tone is how much of the ground they cover. One quantity carries both the bit and, through the elements’ sizes, an image — exactly as a stipple drawing does.
What was interesting to build
The hard part was not generating the code, it was the constraint solver: placing scene elements so that every module lands inside its required lightness band while the arrangement still reads as an intentional object from a human viewing angle. Those two objectives pull against each other constantly, and the scene has to stay decodable under real scanner tolerances rather than ideal ones.
Validation ran against actual decoders rather than a theoretical model of one, because the error correction and binarisation thresholds in the wild are what decide whether it works.
Why it is not open
This is the one I would most like to show the code for, and the one I am holding back. If you want to talk through the solver or see it run, ask me on a call.