Phosphor — Vintage oscilloscope simulator with multi-pass phosphor rendering

Hi! I built a web-based oscilloscope simulator using Three.js and custom GLSL shaders.

Live Demo | Source (MIT)

The rendering uses a 4-pass pipeline:

  1. Beam — point sprites with additive blending into HalfFloat textures
  2. Phosphor — exponential decay persistence in linear HDR (ping-pong buffers)
  3. Bloom — separable 13-tap Gaussian at half resolution
  4. Composite — Reinhard tone mapping, barrel distortion, scanlines, vignette

The key was keeping the phosphor buffer in linear HDR space and only tone mapping once in the composite pass. Per-frame tone mapping causes values to converge instead of accumulating naturally.

Features: Lissajous figures, waveform synthesis, AM/FM modulation, real-time audio visualization (Web Audio API), and freehand vector drawing with keyframe animation.

Built with Three.js, TypeScript, and Vite. Runs in Docker for local dev.

Would love feedback — especially on the phosphor decay approach. I went with exponential decay in linear HDR space, clamped at 2.5 to give Reinhard headroom.

7 Likes