Stereo, rocking and 3D
The depth map makes the stacked result a relief, and a view from the side is that relief sheared: every pixel slides sideways in proportion to its depth. From one camera that never moved sideways, you get a stereo pair, a rocking animation, and a 3D model.
The shear
lapstack shears the stacked image and its depth map in one pass, using Zerene's parameter: the far end of the stack moves ±PCT % of the width relative to the near end, with the middle of the stack staying put. Around ±3 % suits most subjects. For a scene d deep and w wide, a viewing angle a corresponds to tan(a)·d/w.
The shear is a forward warp, row by row. Consecutive samples less than two pixels apart in the view form a patch of surface and are rasterized with a nearness test, so a near edge slides over the background. A larger gap is a depth discontinuity, and the hole it opens is filled from the farther side — the background shows through, rather than the foreground being stretched, which is the less objectionable of the two errors.
Zerene gets the same picture by shifting each frame by its index before stacking; Helicon projects the textured 3D model it builds from the depth map. lapstack's shear has no halo, because it involves no fusion — but it has only one surface, so there is nothing behind an edge to reveal.
The refold
method in the Save step's stereo section: the shear, or the refold.
The refold is Zerene's own way. The frames are read again and the stack is fused once per view, with every frame shifted sideways in proportion to its index. Each view is then a real LAP stack — no depth map is involved — so hair and bristles come out as they would have from a camera actually moved to the side.
The trade:
- Shear: one pass, no halo, one surface. Fast.
- Refold: one pass over the frames per batch of views, genuine parallax through fine structures, and the method's own halo — beside a near object the far frames win (the background is sharp in them) and carry the object's defocused copy displaced by the shift, so a soft ghost stands next to it, wider with a larger shift and a deeper scene.
The stereo pair is folded at full resolution; its two accumulators are about a gigabyte at 45 megapixels, so they go in one batch and the run's own accumulator serves as the first. A rocking sequence is folded at the animation's size, each warped frame block-averaged by an integer factor and shifted by a whole number of source pixels — so a 24-view cycle at 1600 px is one batch and one pass. Views are batched to a 1 GB budget of accumulator memory.
Stereo pair
stereo shift and layout in the Save step; --stereo PCT[:LAYOUT] on the command line.
Two views, at −PCT and +PCT, written as <stem>_stereo.<ext>:
| Layout | Arrangement |
|---|---|
sbs | Left, then right — for parallel (wall-eyed) viewing. Default |
cross | Right, then left — for cross-eyed viewing |
anaglyph | Red–cyan, one image |
Rocking animation
rocking shift and frames per cycle in the Save step; --rocking PCT[:N] on the command
line, default 24 views.
The shift sweeps ±PCT through one sine cycle, so a player's loop is seamless. On the
command line the views are written to <stem>_rocking/view_NN.<ext> to be joined with ffmpeg
or ImageMagick, and --video FPS joins them itself into <stem>_rocking.mp4 (H.264, CRF 18)
when ffmpeg is on the path — the command to run by hand is printed when it is not.
In the browser, rocking is one of the animations and comes out as a GIF, an MP4 or a WebM directly.
Which end is near
This decides who wins where surfaces overlap, and getting it wrong gives you a relief that looks inside out.
near end in the Save step, --near-end on the command line:
| Setting | Meaning |
|---|---|
auto | Default. Read the focus distance the camera recorded in the first and last frames — focus went from the smaller distance to the larger — and fall back to frame 0 near when there is none |
first | Frame 0 is the near end |
last | Frame 0 is the far end (--far-first is the same thing) |
The standard EXIF SubjectDistance is read by lapstack itself, from the TIFF structure or the
XMP. Most cameras keep the distance in their MakerNote instead — Nikon's is even encrypted —
so when exiftool is on the path the command line asks it for SubjectDistance, FocusDistance,
Canon's FocusDistanceUpper and Lower, and Sony's FocusDistance2. The browser has its own EXIF
reader and cannot see into a MakerNote, so a stack whose camera keeps the distance there falls
back to frame 0 near; the section's status line says which cue, if any, decided.
The frames' scale over the stack is logged as a hint but does not decide. On a rail, or with a lens that extends to focus closer, the near frames are the larger ones and a stack shot near to far is enlarged toward its end. An internal-focus lens that widens as it focuses closer breathes the other way. The sign says nothing without knowing the lens.
The symptom of the wrong choice is a relief that looks inside out, and the run logs which cue decided — so if it looks wrong, set it explicitly.
3D model
3d in the Save step's file list; --mesh glb,obj,stl on the command line.
The depth map as a mesh: a grid of vertices over the image, raised by the depth, textured with the stacked image. Each vertex takes the mean depth of the cell of pixels around it, so the mesh is smooth at its own scale, and each cell is cut along the diagonal with the smaller depth step.
| Format | What you get | Opens in |
|---|---|---|
glb | One self-contained glTF 2.0 binary with the texture inside | Windows 3D Viewer, macOS Quick Look, Blender, every web viewer |
obj | .obj + .mtl + a texture file — what Helicon writes | Most 3D software |
stl | Binary STL, geometry only | Printing |
| Control | Command line | Default |
|---|---|---|
| Relief depth | --mesh-relief PCT (% of image width) | 25 |
| Vertices along the long edge | --mesh-grid N | 1000 |
| Texture long edge and format | --mesh-texture EDGE[:jpeg[:Q]|png] | 8192, jpeg:92 |
Coordinates are right-handed with the width as the unit: x along the width, y up, z toward
the viewer, the far end of the stack at z = 0 and the near end at --mesh-relief % of the
width.
The relief depth is the one thing the depth map cannot know. The depth map measures distance in frame indices; converting that to a physical proportion of the image width requires knowing your step size. Measure the subject, or set it by eye.
A depth discontinuity becomes a wall between the near surface and the far one. A heightfield has no way to show what is behind an edge — the same limitation Helicon's viewer has.
The browser's model row shows a thumbnail of the stacked image lit as the relief would be, and reports vertex and triangle counts with a size estimate. The texture is eight-bit in the card's image format, and the model is cropped like the other files. No content credentials are attached to 3D files.