I wanted my pixel games to look like they're running on an old arcade monitor, not a crisp modern LCD. Most AI attempts gave me faint horizontal lines and called it a CRT, which fools nobody.
Asking for "scanlines" got me a 10% opacity line pattern and nothing else. A real CRT look needs scanlines PLUS barrel distortion, phosphor bloom, chromatic aberration at the edges, a subtle vignette, and a bit of flicker. I wrote the prompt to enumerate all of those as a WebGL post-process pass with intensities I could dial back.
Two answers below, both improved it. Curious how far people push the aberration before it's too much.
Write a reusable CRT post-processing effect for a 2D canvas game, implemented as a WebGL fragment shader that samples the game's rendered frame as a texture (single HTML file, vanilla JS, render the game to an offscreen canvas, then draw it through the shader to the visible canvas at 60fps).
The shader must combine ALL of these, each with a uniform so intensity is tunable 0..1:
1. Barrel/pincushion distortion (screen curvature) that bends the edges outward slightly.
2. Scanlines: darkened horizontal bands scaled to the output resolution, with a slow vertical roll option.
3. Aperture-grille / RGB subpixel mask that tints columns r/g/b faintly.
4. Chromatic aberration that increases toward the screen edges (sample r/g/b at slightly offset UVs).
5. Bloom/phosphor glow on bright pixels (cheap 1-pass blur of the bright areas, added back).
6. Vignette darkening the corners, plus a very subtle brightness flicker (sine + a little noise).
Constraints: keep it a single extra draw pass (budget under 1ms on a mid laptop); expose a `crtStrength` master uniform that scales everything so I can dial it 0 (off) to 1 (heavy). Default to a tasteful ~0.5. Respect prefers-reduced-motion by disabling the roll and flicker. Comment each effect block. Do NOT fake it with a CSS overlay; it must be a real shader sampling the frame texture.