Quiltwright
Holographic output for Looking Glass displays.
Eric G. Suchanek, PhD — Flux-Frontiers
Quiltwright turns a rendered scene into a quilt — the tiled multi-view image that Looking Glass lenticular light-field displays fuse into real, glasses-free depth. It renders from PyVista/VTK scenes or from POV-Ray ray-traced scenes, manages the depth budget that decides whether a hologram fuses or ghosts, and drives Looking Glass Bridge directly.
Centre view of a 48-view quilt, ray-traced from a POV-Ray scene first composed in 1994.
Why this exists
The hard part of light-field rendering is not tiling images into a grid. It is that each view must use an off-axis (asymmetric-frustum) projection — the camera slides sideways while continuing to face the same direction, and the image plane is sheared back onto the original view axis.
The intuitive alternative is to swivel each camera to keep the subject centred. That is "toe-in", and it introduces vertical parallax and keystone distortion, so the display cannot fuse the views. You get ghosting instead of depth. This is the single most common way light-field renders go wrong, and it produces output that looks plausible in any individual frame.
Quiltwright does the off-axis projection correctly in both backends, and gives you the arithmetic to know in advance whether a scene will fuse.
Install
pip install quiltwright # core: quilt geometry + Bridge control
pip install "quiltwright[viz]" # + PyVista/VTK rendering backend
The POV-Ray backend needs a povray binary on PATH rather than a Python
package:
brew install povray # macOS
For the complete stack — renderers, ffmpeg, Looking Glass Bridge, pdb2pov — see the installation guide.
Quick start
From a PyVista scene
import pyvista as pv
from quiltwright import QUILT_PRESETS, render_quilt, save_quilt
p = pv.Plotter(off_screen=True)
p.add_mesh(pv.ParametricTorus())
spec = QUILT_PRESETS["portrait"]
save_quilt(render_quilt(p, spec), "torus", spec) # -> torus_qs8x6a0.75.png
From a POV-Ray scene
The scene file is never modified — each view wraps it with #include and
appends one camera.
from quiltwright import QUILT_PRESETS, PovCamera, render_pov_quilt, save_quilt
camera = PovCamera(location=(15, 20, 6), look_at=(44, 19.2, 45.1), fov=53.13)
spec = QUILT_PRESETS["16-landscape"]
quilt = render_pov_quilt("pov-scenes/museum/museum.pov", spec, camera,
include_paths=["pov-scenes/myinclude", "pov-scenes"])
save_quilt(quilt, "museum", spec)
The museum scene above ships in pov-scenes/, and scripts/render_museum_hologram.py renders it end-to-end with a measured depth budget — it is the worked case study in docs/povray.md.
Send it to the display
from quiltwright import cast_quilt, pause_quilt, resume_quilt, stop_quilt
cast_quilt("museum_qs8x6a1.77778.png", spec) # needs Looking Glass Bridge >= 2.2
Saved filenames carry the _qs<cols>x<rows>a<aspect> suffix that Looking Glass
Studio and Bridge parse, so playback settings are detected automatically.
The depth budget
Whether a hologram fuses comes down to adjacent-view disparity: how far a feature moves between neighbouring views. Roughly 4–5 px is the practical ceiling; past ~8 px, hard edges ghost.
from quiltwright import QUILT_PRESETS, focal_distance_for_range, view_disparity
# Put the focal plane where near and far content are equally penalised.
focal = focal_distance_for_range(near=32, far=100) # harmonic mean, not midpoint
view_disparity(QUILT_PRESETS["16-landscape"], fov=53.13,
focal_distance=focal, depth=32) # -> px between adjacent views
Three results worth knowing before you frame a shot:
- Content at the focal plane has zero disparity — it is welded to the glass.
- The focal plane belongs at the harmonic mean of the depth range, not the midpoint. Disparity is asymmetric in depth, and near content is the expensive side.
- A narrower field of view increases disparity. Zooming in magnifies the scene and the parallax with it. The widely repeated "use ~14° FOV" advice is specific to object-centric scenes; applied to an interior it makes ghosting worse.
For interiors there is a fourth trap that no arithmetic will warn you about:
the camera sweep physically travels focal_distance × tan(cone/2) sideways,
and in a room that path can run through a wall. See
docs/povray.md.
Supported devices
QUILT_PRESETS carries the official quilt settings for Portrait, Go, and the
16″/27″/32″/65″ panels in both orientations. The 16″ Gen3 Landscape entry is
verified against what Bridge reports for real hardware.
from quiltwright import QUILT_PRESETS
QUILT_PRESETS["16-landscape"] # 8x6 views, 7680x4320, aspect 1.7778
Documentation
| Document | Contents |
|---|---|
| docs/install.md | Installing the full stack: package extras, POV-Ray, ffmpeg, Bridge, pdb2pov |
| docs/lfd.md | Light-field output, Bridge/Studio setup, device presets, the PyVista path |
| docs/povray.md | The POV-Ray backend: off-axis camera derivation, depth budget, sweep clearance, a worked case study |
| docs/pdb2pov.md | Rendering molecular structures from PDB files as holograms |
| docs/hld.md | Hololuminescent Displays, which play ordinary 2-D video rather than quilts |
Two different technologies. Looking Glass sells a light-field line (Portrait, Go, 16″/27″/32″/65″ LFD) that consumes quilts, and a Hololuminescent line (16″/27″/86″ HLD) that plays ordinary video behind a fixed holographic optic.
quiltwright.lfdtargets the first;quiltwright.hldtargets the second.
Testing
pip install -e ".[viz]" && pip install pytest
pytest
Rendering tests skip cleanly on machines with no OpenGL stack, and the POV-Ray
tests skip when no povray binary is present. Under a headless CI runner, use
xvfb-run -a pytest to exercise them.
Related
- WaveRider — manifold-aware geometric ML; its voxel visualiser renders through Quiltwright.
- proteusPy — protein disulfide bond analysis and rendering.
- pdb2pov — PDB to POV-Ray converter, 1993, still feeds this pipeline.
Citation
If you use Quiltwright in your work, please cite it. Citation metadata is in CITATION.cff; GitHub's "Cite this repository" button generates BibTeX/APA from it, and the DOI badge above resolves to the archived release on Zenodo.
@software{suchanek_quiltwright,
author = {Suchanek, Eric G.},
title = {Quiltwright: Holographic Output for Looking Glass Displays},
url = {https://github.com/suchanek/quiltwright},
version = {0.1.0},
year = {2026}
}
License
BSD 3-Clause. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quiltwright-0.1.0.tar.gz.
File metadata
- Download URL: quiltwright-0.1.0.tar.gz
- Upload date:
- Size: 28.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.3.2 CPython/3.12.13 Darwin/27.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ed6dad84283c6866645891fcf15017c824b9cf34b58f35f1b2e181ed4356ac3
|
|
| MD5 |
b818eee2cadba51447ec11913a90a57e
|
|
| BLAKE2b-256 |
5b8906bfcee798df71d03eb01c8b783bec87ea48b64cac8d882d0d863b64d1f8
|
File details
Details for the file quiltwright-0.1.0-py3-none-any.whl.
File metadata
- Download URL: quiltwright-0.1.0-py3-none-any.whl
- Upload date:
- Size: 29.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.3.2 CPython/3.12.13 Darwin/27.0.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72522db88b157ee3035c36d9d41878cf667efa411b0568af488795bdddda5799
|
|
| MD5 |
50fe0596381761f8734518b6359cc2c0
|
|
| BLAKE2b-256 |
f6bcb6bd0efc078549e2ff7b2044945aa2a32de85a3b2bddb3754eabdb5650e9
|