Mockup v19. Scintillation speed is now its own control, independent of the rotation. The trick is that one clock advances both the seed and the pose, so a slow noise rate simply repeats frames rather than holding the pattern still while the object keeps moving — which is what would have leaked. Rotation stays on its own knob, and the pose step per tick is reported so you can keep it under the blades' aliasing limit.
Decode pauses the video, correlates each row of the finished frame against itself across the plausible separation range, then inverts the separation formula back to depth. Flat planes come back around 0.88; slanted faces read lower, because a fixed-width window cannot match a stretched copy of itself. On a solid, treat 0.7 as a pass. Compare the pictures rather than the number — if the right panel looks like the left, the geometry is encoded and what remains is a viewing problem.
Not run yet.
Eight blades, 170 px long by 40 across, hub 26, 336 px overall. Blades merge into a solid core at r = hw/sin(π/n) = 52, leaving 118 px of each blade free. A run narrower than one separation has nothing to pair with, so the period sits at 44 and the separation at 26 — under the 40 px blade width with room to spare.
Gap is the separation, in pixels, between the wall and the object's rearmost visible point. μ is the whole budget and gap eats into it, so relief reports what is left and how much the current pose uses. The split matters more than the total: a real ball floating in front of a wall has a step to the wall many times larger than its own front-to-back depth, so a gap-heavy split is what reads as detached. A relief-heavy split reads as the wall bulging. Each subject loads its own split — the ball 32/14, the whale 16/29 — because the whale has a shape to be read and the ball does not.
Background phase is assigned, φ(x) = x, not integrated, so drift is not representable. Each run of object pixels is integrated from whichever side has background beside it, with the residual dumped at that run's own right silhouette.
Static object texture takes the object's phase from φ(x) = x + (p−s)·floor(x/s) with s snapped to a whole pixel. That satisfies φ(x+s) − φ(x) = p exactly, mentions nothing about where the object is, and is integer throughout, so there is no resampling and nothing to change from frame to frame. It needs the depth to be piecewise constant; a row with any gradual separation change falls back to the chain, which does re-link every frame. Turn it off to see the difference — a third of the object repaints per frame.
Own texture gives the object a second noise field — same statistics, same period, uncorrelated with the wall — so its boundary is an occlusion edge rather than a continuation of the wall's surface.
Mark invented columns paints the pixels no stereo constraint reaches. They are the leading strip of every blade, one separation wide, and they are why coverage tops out around two thirds.
Noise rate is the tick rate, and one tick advances both the seed and the pose. Between ticks the frame is repeated byte for byte, so slowing the scintillation down does not expose anything — nothing moves during a hold either. That is what makes the speed independent of the rotation: the pose step per tick is 360° ÷ (period × rate), reported as step.
Watch that step against the subject's own symmetry. Eight blades repeat every 45°, so a step over 22.5° aliases and the propeller starts turning backwards — the wagon-wheel effect. The readout flags it.
A pixel crossing the silhouette jumps a whole gap in phase, so it decorrelates completely. For that to be unremarkable, every other pixel must decorrelate completely on the same tick — no temporal correlation anywhere, at any lag or any shift. Reseed hold above 1 breaks that on purpose by letting the pose tick on while the seed sits still.
Noise drift translates the field rigidly instead. It is kept only as the counter-example: it passes the leak meter at 1.00× and is still wrong, because a uniform flow field is something the silhouette can stand out against. The coherence readout is what catches it — the largest frame-to-frame cross-correlation of the wall over any horizontal shift. Scintillation reads a few percent; a drift of 5 px/frame reads near 100% at −5 px, and a reseed hold reads near 100% at 0.
Drift and hue are redundant once refresh is on. Tint stamps the silhouette at every pattern repeat, which is why it starts at zero.
Guard active. 4:2:0 and crf > 12 are refused: chroma subsampling averages the very pixel pairs that carry the depth. A reseeded field also has no temporal redundancy at all, so every frame costs a full intra frame. Measured by gzipping one: 62 KB colour, 17 KB in black and white, which extrapolates to roughly 60 and 16 Mbps at 1920×1080. Classic dynamic stereograms are two-tone for exactly that reason.
3MF / OBJ / STL mesh, 16-bit depth PNG sequence, EXR, or a procedural primitive. Meshes are decimated to a triangle budget on import.
One depth mapping for the whole rotation, gap subtracted from the μ budget. A per-frame fit is refused: it makes a rigid solid breathe.
Coverage, spatial grain, the leak ratio, and the coherence of the wall between frames. Magnitude alone is not enough — a coherent flow field passes the leak test and still gives the shape away.
Δ per row per frame, before any pixel is written. Rows over the band budget are flagged, not silently bent.
Dual-anchor phase integral, occlusion mask, fractional wallpaper lookup. Loop over x, vectorized over y.
Every hundredth frame is decoded back to depth and compared against the input. A falling match ends the run.
MKV / MP4 / PNG sequence, plus sidecar JSON with period, separation, target pitch and viewing distance.
| Job | Frames | Relief | Compensation | Max Δ | Decode match | State |
|---|---|---|---|---|---|---|
| prop_scint | 96 | 0 px | reseed per frame | 0.0 px | 0.81 | Baking |
| prop_drift5 | 96 | 0 px | drift 5 px/frame | 0.0 px | 0.81 | Blocked — coherence 99% at −5 px |
| ball_edge_exit | 384 | 29 px | frame-edge anchor | 47.3 px | 0.84 | Blocked — anchor lost on edge contact |
| whale_raw_96k | 384 | 35 px | dual anchor | 0.0 px | — | Held — 95,686 tris over budget |
| cube_16s_v3 | 384 | 7 px | dual anchor | 0.0 px | 0.44 | Blocked — relief below floor |
| wedge_cal | 1 | 35 px | dual anchor | 0.0 px | 0.88 | Done |
| cube_9s_nolock | 216 | 35 px | none | 56.7 px | 0.70 | Done — reference |