Your sRGB Display Covers ~35% of Human Vision. Here's Where the Rest Lives.

5 min read 1 source explainer
├── "Consumer displays fundamentally cannot reproduce most spectral colors due to geometric limits of three-primary systems"
│  └── Ryan Moulton (moultano.wordpress.com) → read

Moulton argues that sRGB covers only ~35% of human-visible chromaticity and even Rec. 2020 reaches just ~75%, because any triangle defined by three primaries cannot fully inscribe the convex horseshoe of the spectral locus. The gap isn't a niche edge case — it includes most greens humans can see between 490-540 nm.

└── "The way to truly appreciate these missing colors is to seek them out in the physical world"
  └── Ryan Moulton (moultano.wordpress.com) → read

Rather than dwelling on abstract chromaticity charts, Moulton catalogs specific physical phenomena — soap films, fluorite under UV, 532 nm laser pointers, Morpho butterfly wings, peacock coverts, dichroic glass — where viewers can directly experience out-of-gamut colors. He treats the post as a field guide, turning a 95-year-old CIE diagram into a 'walk-around-the-world experience.'

What happened

A blog post by Ryan Moulton — "Where to Find the Colors Your Screen Can't Show You" — hit 211 points on Hacker News this week. It's a guided tour of the color volume that sits outside every consumer display ever shipped, with photographs and physics for each region: spectral cyans in soap films, deep violets in fluorite under UV, the saturated green of a 532 nm laser pointer, the structural blues of *Morpho* butterfly wings.

The premise is unintuitive but verifiable: sRGB — the gamut nearly every web page, JPEG, and stock photo is encoded in — covers roughly 35% of the area of human-visible chromaticity. Display P3, the wide-gamut standard Apple shipped across iPhone, iPad, and the entire Mac lineup, adds about another quarter. Rec. 2020, the UHD broadcast target, gets to ~75% but requires near-monochromatic primaries that no LCD backlight and almost no OLED stack can actually hit. The colors in the gap aren't subtle edge cases — they include most of the spectral locus from about 490 nm to 540 nm, which is to say *most greens humans can see*.

Moulton's contribution isn't the math (the CIE 1931 chromaticity diagram has been around for 95 years). It's the catalogue of where to actually *go look*: prisms, oil slicks, dichroic glass, fluorescent minerals, peacock coverts, butterfly wings, and lasers. The post is doing what good explainers do — turning a chart most engineers have squinted at into a physical, walk-around-the-world experience.

Why it matters

The geometric problem is fixed and uncomfortable. Human color vision plots onto a horseshoe-shaped region whose outer boundary — the spectral locus — is convex, while any display built from three primaries can only paint colors inside the triangle those primaries define. You cannot inscribe a triangle in a convex curve and cover it. You can pick wider primaries (laser projectors, quantum-dot enhancement films, the deep-red phosphors in modern QD-OLED), but the corners of the horseshoe — particularly the long cyan-green arc — remain unreachable in principle. Add a fourth primary and you get a quadrilateral, still inscribed, still leaving slivers behind. Sharp's defunct Quattron TVs tried this with a yellow subpixel and it mostly bought marketing copy.

This matters because color tooling on the web has spent thirty years pretending the problem doesn't exist. Photoshop has had wide-gamut workflows since the 2000s, but the browser pipeline — CSS hex colors, ``, default JPEG decoding — has been sRGB-locked until very recently. Safari shipped `display-p3` color in CSS in 2016; Chrome and Firefox followed years later. CSS Color 4 (`color()`, `oklch()`, `color-mix()`) finally gave the web a syntax for talking about colors that aren't sRGB, and the `color-gamut` media query lets you branch on what the display can actually do. But the defaults are still sRGB, the design tokens in most component libraries are still sRGB hex, and the figure of merit most engineers cite — "contrast ratio" — is computed in a colorspace that doesn't match how eyes work.

The wild card is that even "unreachable" doesn't always mean unreachable: in 2024, a Berkeley team stimulated single M cones in volunteers' retinas with laser pulses and reported a saturated blue-green called "olo" that sits outside the human gamut entirely. That experiment ran with a hardware rig the size of a desk and a contact lens with fiducial markers, so nobody's shipping it in a Vision Pro. But it makes the point sharper: the chromaticity diagram itself is a projection of a higher-dimensional cone-response space, and the reason most of color science assumes you can't excite one cone class in isolation is that *broadband light always hits all three*. Lasers and direct retinal stimulation are the exceptions.

The community reaction on HN split, predictably, between the "I had no idea my MacBook was lying to me" crowd and the color scientists pointing out that the post understates how good Rec. 2020 mastering has gotten in the last five years. Both are right. The gap between display capability and human perception is shrinking — QD-OLED panels from Samsung Display now cover ~99% of DCI-P3 and ~80% of Rec. 2020 — but the asymptote is fixed and the marketing curve keeps approaching it.

What this means for your stack

If you ship a UI that cares about color — design tools, photo editors, dashboards with semantic color, anything with a brand palette — three concrete moves are overdue. First: stop authoring brand colors as sRGB hex and start authoring them in `oklch()` or `color(display-p3 …)`, with sRGB fallbacks generated by your build pipeline rather than by hand. Modern Tailwind, Radix, and Open Props ship P3-aware tokens; if your design system was written before 2023, its reds are duller than they need to be on roughly every Apple device sold in the last decade.

Second, feature-detect rather than assume. The CSS `@media (color-gamut: p3)` query is well-supported and lets you serve a wider palette only where the display can render it. For canvas and WebGL work, the `colorSpace: "display-p3"` option on `getContext()` and `createImageData()` has been in Chrome and Safari since 2022; if your image pipeline is still doing manual `Uint8ClampedArray` writes assuming sRGB, you're throwing away pixels on every modern phone. Image tags accept `image-rendering` and ICC profiles embedded in the file — let the browser do the conversion instead of pre-flattening.

Third, if you're doing anything color-critical in machine learning — diffusion models, image super-resolution, automated grading — check what colorspace your training data is in. Most public datasets are sRGB JPEGs because that's what the web served for twenty years. Models trained on them will systematically desaturate wide-gamut input at inference, which is one of the underdiscussed reasons AI-generated images often look slightly flat against photographs. The fix isn't algorithmic; it's preprocessing discipline.

Looking ahead

The direction of travel is clear and slow. Laser-illuminated cinema (Dolby Cinema, IMAX with Laser) already hits ~98% of Rec. 2020 in commercial deployment; the same primaries are creeping into projection TVs and will eventually land in phones once the power and speckle problems get solved. Five-primary research displays exist in academic labs. Direct retinal projection — the technology behind the "olo" experiment — has obvious accessibility and AR applications a decade out. None of this closes the gap with the horseshoe, but it narrows it enough that the visible difference between "display" and "real life" becomes the kind of thing only color scientists notice. For everyone shipping software today, the actionable version is shorter: assume your users' screens are better than your CSS thinks they are, and stop encoding the brand in 1996.

Hacker News 399 pts 105 comments

Where to Find the Colors Your Screen Can't Show You

→ read on Hacker News

// share this

// get daily digest

Top 10 dev stories every morning at 8am UTC. AI-curated. Retro terminal HTML email.