Why this works
The image genuinely does not know. Take a cloud of dots on the surface of
a sphere, turn it about the vertical axis, and draw it with an orthographic camera: no
perspective, every dot the same size and the same brightness whatever its depth, nothing
hidden behind anything. Now mirror the whole thing in depth, so every point at z
moves to −z, and turn it the other way. The two produce
pixel-identical images, forever, because the projection throws away the coordinate
the two versions differ in. This is not an artist’s trick or a near-miss; it is an
exact algebraic degeneracy. What you see is therefore not a reading of the evidence —
the evidence is silent — it is a construction your visual system commits to and then
defends. Wallach and O’Connell called the general phenomenon the kinetic depth
effect in 1953: a flat moving shadow spontaneously acquiring a solid
three-dimensional form. The reversals are the interesting part. A system that had merely
computed the answer would not keep changing it.
What it costs to keep the image honest. Almost every piece of graphics
code you would write by reflex is a depth cue, and any one of them silently ends the
illusion. Perspective divide: a cue. Scaling dots with distance: a cue. Fog, shading,
occlusion, z-sorting with opaque fills, a drop shadow: all cues. So the renderer here is
deliberately impoverished. Projection is orthographic — (x, y, z) → (x, y),
no divide. At help = 0 every dot in a cloud is the same size and the same alpha
and the cloud goes down as one fill per colour, so there is no per-dot state that could leak
depth; a wire is stroked as one path at one width; the silhouette is the nonzero-winding
union of every triangle filled flat, which is why it has no interior line at all. Every loop
is animated from phase = (t mod period) / period and never from an accumulated
delta, so the frame at phase 0 is bit-identical to the frame at phase 1 and a recording of
one period loops without a seam. The help dial is the same code path with the terms switched
on: scale = 1/(1 − help·k·z) for perspective, radius
× (1 + help·z·k) for size, alpha falling off with depth. At
help = 0 each of those expressions is exactly its identity, which is the
property that makes the claim checkable rather than aspirational.
Where the look comes from. Each object spins about its own axis,
tipped fifteen to twenty degrees towards you, so the top of it traces a visible circle.
Nothing is filled: each one is a few thousand tiny dots sampled uniformly by area
over its surface, at one size, with no occlusion. Where the surface turns edge-on, a whole
band of it projects into a couple of pixels and the dots stack, so the rim lights itself;
where it faces you they spread out and it goes dim. That is the whole shading model, and it
is free, because it is a fact about the projection rather than a thing drawn on top of it.
Colour follows two safe rules: it can be attached to the object (the tetrahedron’s
pink corner is pink in either reading), or it can be a function of the projected image (the
ring arrow’s gold-to-blue gradient is keyed to how high a dot lands on the
screen). Colouring by depth would have ended the illusion and is used nowhere. If you
would rather have none of it, the palette switch in the app’s details drawer has a
mono setting that throws all the colour away, which is the honest control.
One technique that did not fit on a card. Slow it down. Longer periods are
more ambiguous and much easier to steer; speed stabilises the percept, which is why the
drill gets harder as you shorten the period. The period slider is in the details drawer.
Honest weaknesses
They are not equally good, and the order on this page is the honest order. The ring arrow
is first because it is the loop that went round and because its silhouette never changes at
all, so there is nothing to read but the head going round. The chair is the same trick
applied to an object you have opinions about, and it is noticeably stickier for exactly that
reason. The straight arrow is the cleanest case in the set: an arrow of revolution is
mirror-symmetric about its own vertical plane, so its depth-mirror is the same arrow,
and the two readings are the same picture rather than two theories about a picture. The coil
is the one place the mirror argument has to be stated carefully — a helix is chiral, so
its depth-mirror is the opposite-handed spring rather than the same object; the picture still
cannot tell the two readings apart, it just cannot tell you which spring you are looking at
either. Sphere and cylinder are the lab standards and they flip freely for almost everyone.
The cube is a Necker cube in motion and flips readily, but the flip is as much a figural
reversal as a motion reversal, which is a slightly different phenomenon wearing the same
coat. The ring is the crispest of the lot for some people and stubborn for others, because
thirty-two dots on one ellipse is very little evidence and the percept can lock. The
silhouette depends heavily on the shape: this one is a lathe-turned vessel with a spout,
which reverses well when the spout is near the edges of its sweep and rather less well when
it is pointing straight at you. The last one is the honest failure. It is named
dual-axis after Frank Force’s 2019 Best Illusion of the Year, in which a
single loop reads as spinning about a vertical axis and about a horizontal one; what
is shipped here is a tennis-ball-seam curve turning about an axis that leans out of the
screen, so its two readings are “leaning towards me” and “leaning
away” — a real second axis, but not the vertical-versus-horizontal read that
makes Force’s version famous. Finally: none of this measures your percept. It records
the key you pressed. Every number on the site is a number about your reporting, which lags
the flip by a reaction time and can be wrong on purpose, and there is no way around that in
a browser.
Where the loops come from
Nothing here is copied, traced or embedded — every loop is drawn from scratch in a
few hundred lines of canvas code, and the shapes are chosen to echo the ones that travel.
The ring arrow is the refresh-arrow loop that circulates as a
“which way is it spinning?” post; the silhouette is the
spinning-dancer family, which Nobuyuki Kayahara made a mass phenomenon in 2003; the
dual-axis knot is named after Frank Force’s 2019 Best Illusion of the
Year; the sphere, cylinder and Necker cube
are the laboratory stimuli the papers below use, and Michael Bach’s implementation is
the reference everyone checks their version against.
References
- Wallach, H. & O’Connell, D. N. (1953). The kinetic depth effect.
Journal of Experimental Psychology 45(4), 205–217 — the founding demonstration
that a moving flat shadow is seen as a solid.
- Kayahara, N. (2003). The spinning dancer — the silhouette version that
made this class of illusion a mass phenomenon.
- Force, F. (2019). Dual Axis Illusion, Best Illusion of the Year Contest —
illusionoftheyear.com.
- Bach, M. Structure-from-motion / kinetic depth effect —
michaelbach.de/ot/mot-sfm/.
- Pastukhov, A., Vonau, V., Stonkute, S. & Braun, J. (2012). The role of attention
in ambiguous reversals of structure-from-motion. PLOS ONE 7(6): e37734 —
journals.plos.org.
- Treue, S., Husain, M. & Andersen, R. A. (1991). Human perception of structure
from motion. Vision Research 31(1), 59–75 — the transparent-cylinder
stimulus used here.