Materializr
Open-source parametric 3D CAD for makers — constraint sketches, solid modeling, threads, SVG & text engraving, STL/STEP export. Android, iPad, Linux, Mac, Windows. Vibe coded.
Physically based screen × camera moiré simulator (LCD, OLED, CRT, LED walls) in WebGL2
Translation pending
DesignJavaScript · CSSGitHub @sohrobxyzOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A physically based simulator of photographing a screen. Moiré here is not drawn. It emerges, as it does in real photos, from sampling a periodic emitter (the panel's subpixels or phosphor mask) with a periodic sampler (the camera's photosites and colour filter array).
Try it in the browser: https://sohrobxyz.github.io/moire-lab/
To run it locally, open index.html in Chrome, Safari or Firefox. It needs WebGL2. There is no build step and no server. Load a photo, drop one onto the page, or paste one, then pick a preset.
| Stage | Model |
|---|---|
| Panel framebuffer | The source is box-filtered into the panel's native pixel grid in linear light (sRGB decoded). The black level adds backlight leakage. |
| LCD | RGB or BGR vertical stripes with a black matrix (X/Y), the TFT corner notch, and the IPS chevron skew. Radiance is normalised so each pixel's area mean equals its framebuffer value. |
| OLED PenTile | A green oval at every pixel centre. Red and blue diamonds sit on the corner lattice in a checkerboard, with subpixel-rendered values (the average of the 4 pixels they serve). The blue emitter is larger. |
| LED wall | Three small round dies per pixel on a mostly black field. |
| CRT | The video signal is band-limited along each line (Gaussian, in signal px). Each gun's beam has a Gaussian vertical profile whose σ grows with beam current (bloom), and energy is conserved. Three mask types: aperture grille (with damper wires and a cylindrical faceplate), delta shadow mask (a triangular 3-coloured dot lattice; the dot pitch is the same-colour distance) and slot mask (staggered bridges). The faceplate bulge is an exact ray–quadric intersection. |
| Time | For CRTs, each line is struck at its raster time. Phosphor emission decays exponentially with a separate τ for R, G and B, and the energy inside each sensor row's exposure window is integrated in closed form (with interlace as an option). For flat panels, there is a PWM backlight or OLED dimming, either global or scan-synced. A rolling shutter offsets each row's window by row/height × readout. This produces the dark/bright bands and the red phosphor trail. |
| Camera pose | A pinhole camera with yaw, pitch and roll. Focal length is given as a 35 mm equivalent. Distance is set by magnification (how many photosites one screen pixel spans). Perspective makes the moiré bands curve. |
| Lens | Defocus is sampled from a uniform disk (the circle of confusion). Diffraction is approximated as a Gaussian with σ ≈ 0.42 λN per channel (λ = 610, 540 and 465 nm), so it depends on f-number and pixel pitch. The model also includes radial distortion, lateral CA and cos⁴ vignetting. |
| Sensor | Photosite aperture (fill factor), a 4-spot birefringent OLPF (or none), and CFA spectral overlap with the display primaries. Available sensors: Bayer RGGB, Fuji X-Trans 6×6, monochrome, or full colour as a control. |
| Readout | Poisson shot noise (full well scaled by ISO), Gaussian read noise, saturation clipping and a 12-bit ADC. |
| Development | Malvar-He-Cutler or bilinear demosaic (or raw mosaic view), a CCM that inverts the CFA response, WB, sRGB or filmic tone curve, in-camera unsharp masking, contrast and saturation. |
Integration is progressive Monte Carlo: each frame adds N samples per photosite, drawn from per-pixel-rotated Weyl/R2 low-discrepancy sequences, into float32 buffers. The output converges to the exact integral over the photosite aperture × OLPF × lens PSF × diffuser × exposure.
index.html?preset=Trinitron%20monitor%20(480p)&roll=2&zoom=1.