Skip to content

The science of grayscale: how monitors lie about contrast

Why #808080 is not 50% gray, how sRGB and gamma curves quietly bend reality, and why OLED, LCD, and HDR each lie about contrast in a different accent.

You probably think 50% gray is gray that's halfway between black and white. It isn't. Or rather, it isn't on your monitor. The pixel value #808080 — the one every design tool calls "middle gray," the one Photoshop hands you when you click the centre of the gradient picker — emits about 22% of the maximum luminance your screen can produce. Not 50%. Twenty-two.

This isn't a bug. It is the design intent of sRGB, the colour space almost every consumer display speaks. The number 128 in your framebuffer is not a luminance; it is an index into a curve, deliberately bent so that the brightness steps between consecutive code values look approximately even to a human eye. Your monitor isn't lying out of malice — it's lying in the way every well-engineered instrument lies, by mapping a non-linear physical quantity onto a linear-looking control surface because that's the only way humans can use it.

This post is for the kind of person who finds that satisfying rather than alarming.

Linear light and logarithmic eyes

Light is linear. Double the photons and you double the energy hitting a sensor. A photodiode plotted against photon flux gives you a straight line through the origin.

Eyes are not photodiodes. The visual system compresses an enormous dynamic range — about ten orders of magnitude from a starlit field to a sunlit beach — onto a much smaller channel of neural firing rates. The compression is approximately logarithmic in the mid-range and follows a power law near the extremes; either way, decidedly not linear. Doubling the photons does not double the perceived brightness. A 60-watt bulb does not look ten times brighter than a 6-watt bulb. Your retina is doing a calculation closer to "how many e-folds of light is that?" than "how many photons?"

Now consider the framebuffer. Each pixel of a standard 8-bit RGB display carries three values between 0 and 255. If you treated those as linear luminance — 0 = none, 255 = max, 128 = half the photons — and stepped from 0 to 255 in equal increments, you'd get a poor distribution of perceptually useful steps. Most of the action between "almost black" and "barely visible grey" lives in the bottom 5% of the linear range. You'd see banding in the shadows and indistinguishable near-whites at the top.

This is what sRGB solves. Instead of treating 0–255 as linear luminance, sRGB treats it as a perceptual index, mapped to physical luminance through a curve that places equal-perceptual-distance gray steps at equal-numerical-distance code values. That curve is the gamma curve. Mid-gray sits, by deliberate construction, near code value 128.

What sRGB actually specifies

The formal sRGB transfer function is not a single power law. It is a piecewise function — a short linear segment near zero (to avoid numerical instabilities and infinite slope at black), followed by a power curve with exponent 2.4 for the rest of the range. The whole thing was tuned so that the effective gamma — the best-fit single power curve — is approximately 2.2.

In code, the inverse-EOTF (electro-optical transfer function, the bit that turns a code value into a normalised luminance) looks like this:

function srgbToLinear(c) {
  // c in [0, 1]; output also [0, 1] normalised luminance
  if (c <= 0.04045) return c / 12.92;
  return Math.pow((c + 0.055) / 1.055, 2.4);
}

That's the spec. In practice, almost everyone — including most display calibration tools — approximates the whole thing as a pure 2.2 power curve, which is wrong by a few percent near black and effectively right everywhere else.

The interesting consequence: plug 128 / 255 ≈ 0.502 into either function. You get pow(0.502, 2.2) ≈ 0.218, or the formal pow((0.502 + 0.055)/1.055, 2.4) ≈ 0.215. Either way: about 22% of maximum luminance. Code value 128 — #808080, the canonical middle gray of every CSS framework and design system — is emitting roughly one-fifth of your screen's white.1

This is the lie. It is also the entire point.

Why sRGB looks right anyway

#808080 looks like middle gray, despite emitting 22% of the photons, because perception has a logarithmic compressor in front of it. Twenty-two percent linear luminance, fed through the visual system's roughly-logarithmic response, lands near the perceptual midpoint between black and white. The sRGB curve is reverse-engineered to make this work: it spreads perceptually-equal steps across the 256 available code values, so the difference between codes 50 and 60 looks roughly the same as the difference between codes 200 and 210 — even though the photon difference is wildly different.

If you stored linear-light pixel values in 8 bits instead, you'd get visible banding in the dark regions — the entire range from black up to a perceptually-dim grey would compress into the first 20-or-so codes. sRGB's perceptual indexing buys you about ten effective bits of perceptual dynamic range out of eight actual bits. Gamma encoding is one of the cleanest examples of designing storage formats around the perceiver, not the underlying physics.

The cost: anyone doing maths on those pixel values needs to know they are in a perceptually-coded space. Average two sRGB values by (a + b) / 2? Wrong — you've averaged the indices, not the light. Resize an image without converting to linear first? You're averaging in gamma space and the highlights will look dimmer than they should. Renderers, image processors, vision tests, and HDR pipelines all spend cycles converting in and out of linear light for exactly this reason.

What this means for contrast

Contrast is where the gamma curve quietly mauls a lot of online vision tests.

Two formal definitions matter. Michelson contrast is (L_max − L_min) / (L_max + L_min) — defined on physical luminances, ranges 0 to 1, ratio-invariant to overall brightness. Weber contrast is (L − L_bg) / L_bg — useful for spots on uniform backgrounds. Both are luminance ratios. Both assume you know what L actually is.

A vision test that uses nominal RGB deltas as a stand-in for contrast — and most legacy online tests do — is not measuring contrast sensitivity. A "5% delta on the 0–255 scale" around mid-gray maps to a physical Michelson contrast that depends on the gamma curve's local slope at code 128, which depends on the user's monitor. Two people on different displays will see different physical contrasts at the same nominal value. The returned number is a polite fiction.

The fix is unspectacular: do your maths in linear-light space, then encode through the inverse gamma at write time. Our test does this; the companion post on screen settings walks through the per-device gamma calibration in detail.

For sub-1/256 contrast steps — necessary for near-threshold psychophysics — 8-bit framebuffers don't have enough resolution even after gamma correction. The standard tricks are adding fine noise before quantisation — the "noisy-bit" method2 — and Tyler's bit-stealing, which trades a little chromatic precision for an effective luminance resolution of 11–12 bits from an 8-bit display.3

OLED vs LCD vs HDR: three different lies

Different display technologies bend reality in different ways. Understanding which lie your monitor is telling matters more than you might think.

LCD. A backlight shines through a colour filter and a liquid-crystal shutter. Black is "the shutter is as closed as it can get" — which still passes a small amount of light. Typical static contrast ratios run from about 1000:1 to 1500:1 for IPS and TN panels (VA-type LCDs reach higher), so black is roughly one-thousandth of white. "Good" by physical standards, "obviously not black" in a dark room. The benefit: luminance linearity. Gamma is well-behaved and contrast is uniform across the brightness range. The cost: blacks bleed, local dimming creates haloes, and viewing angle shifts the gamma.

OLED. Each pixel is its own emitter. "Off" means zero photons, so blacks are physically black and contrast ratios are nominally infinite. The catch is in the bottom 5% of the luminance range: per-pixel emission at very low luminance becomes noisy and discrete, and many panels use a near-black plateau where small code-value differences produce no visible luminance change. If you're testing contrast sensitivity at threshold — where the stimulus delta lives in the bottom few percent of the range — OLED is paradoxically worse than LCD, because the panel's near-black behaviour stops being a smooth gamma curve and starts being a step function. OLEDs also often apply automatic brightness limiters that change the effective gamma based on what's currently on screen.

HDR. A different beast entirely. Standard sRGB assumes a peak luminance around 80–100 cd/m² and an effective gamma of 2.2. HDR formats (HDR10, Dolby Vision) target peak luminances of 1000 cd/m² or more and use entirely different transfer functions — the Perceptual Quantizer (PQ) defined by SMPTE ST 2084, or HLG — designed for a wider dynamic range.4 When a display is in HDR mode, even content tagged as sRGB gets tone-mapped into the HDR pipeline, with surprising side effects on the gamma response. For a calibrated vision test, HDR mode is something to turn off.

This is why our test specifies non-HDR, non-dark-mode, standard sRGB. Those aren't arbitrary restrictions. They are the regime in which the calibration math holds.

Why uncalibrated online vision tests are bad

Roll all of the above up, and the conclusion is unavoidable. A vision test that does not calibrate per-device is testing the screen + OS + room, not the eye.

The variables that drift:

  • Display gamma varies by panel — laptop screens often closer to 2.3, phones closer to 2.0, professional monitors to a near-exact 2.2. Without measuring it, "10% nominal contrast" is anywhere between roughly 8% and 14% physical contrast.
  • Peak luminance varies by 4–6× across consumer devices — a 250-nit budget laptop vs. a 1600-nit professional monitor. Mean luminance affects the visual system's adaptation regime, and contrast sensitivity itself depends on adaptation level.
  • OS filters silently re-map. macOS Night Shift shifts the white point warmer. True Tone adjusts to ambient colour. Windows Night Light does similar. None of these are visible to a browser; all of them change what the user sees.
  • Ambient light adds veiling glare. A glossy phone screen in direct sun adds a constant to both the bright and dark parts of a stimulus, lowering effective Michelson contrast by a factor that can exceed 2.
  • Browser zoom, OS scaling, dark mode all interact with stimulus geometry and luminance in ways that depend on the user's exact configuration.

A "free online contrast sensitivity test" that does none of this is producing a number that varies by a factor of two or more depending entirely on the user's hardware. That isn't a measurement. That's the screen taking a personality test.

The literature has known this for decades. Bach's Freiburg Visual Acuity Test (FrACT) is a long-running, openly documented example of an automated computer-based visual test;5 its documentation treats display calibration — gamma, luminance, and dithering — as a precondition for valid thresholds. Allard & Faubert's noisy-bit method was developed because the 256 levels of an 8-bit display weren't enough for unbiased contrast-threshold measurements.2 And V*(λ) — a modern luminous efficiency function for daylight adaptation, built from the Stockman & Sharpe cone fundamentals to define "what counts as bright" for a calibrated observer — was set out by Sharpe, Stockman, Jagla & Jägle (2005),6 and underpins any test that claims to measure luminance contrast as the visual system uses the term.

What our test does (and doesn't) try to fix

We calibrate four things per-device: pixel pitch (credit-card resize), viewing distance (blind-spot localisation), display gamma (high-frequency stripe match), and adaptation state (30 seconds of mid-gray before any stimulus). The mechanism for each is documented in the calibration post; the trial procedure is on the methodology page; the how-to walkthrough covers what taking the test feels like.

What we assume rather than measure: sRGB colour profile, non-HDR mode, no aggressive OS-level filters, reasonable ambient lighting. We surface these as instructions before calibration and ask the user to confirm.

What we cannot fix: a fundamentally bad display, direct sunlight on the screen, an OLED panel with non-monotonic near-black behaviour, or a system colour profile a browser has no way to query. We characterise the residual error rather than pretending it isn't there. The headline claim is small but honest: a calibrated remote measurement is in the same neighbourhood of test-retest variability as a clinical instrument — not equal to it, but useful and reproducible enough to detect real changes over weeks and months.

The takeaway

Pixel value 128 is not 50% gray. Your sRGB monitor is encoded for your eyes, not your photometer. Different display technologies bend the photons in different ways. Online vision tests that don't measure your specific display are mostly characterising your hardware. The maths to fix it — gamma inversion, dithering, linear-light rendering — is unspectacular and has been in the literature for thirty years.

If you came here wanting to know why #808080 doesn't look like the gray you expected: it does, because your eyes are doing the work the framebuffer can't.

Take our test — the calibration step takes about two minutes and is most of what separates a measurement of you from a measurement of your laptop. For the per-step breakdown of calibration, this post walks through it.

Footnotes

  1. IEC 61966-2-1:1999. Multimedia systems and equipment — Colour measurement and management — Part 2-1: Default RGB colour space — sRGB. The normative sRGB standard; the piecewise transfer function (a short linear segment near black, then a power curve with a 2.4 exponent and an effective gamma near 2.2) is defined here. Plugging code value 128 (0.502) through it gives about 0.215–0.22 of maximum luminance. (IEC standards are paywalled and have no stable free full-text URL, so this is cited without a link.)

  2. Allard R, Faubert J. The noisy-bit method for digital displays: converting a 256 luminance resolution into a continuous resolution. Behav Res Methods. 2008;40(3):735–743. Adds sub-threshold noise before quantisation so that an 8-bit display can render contrast steps finer than 1/256 without biasing measured contrast thresholds. PubMed. 2

  3. Tyler CW. Colour bit-stealing to enhance the luminance resolution of digital displays on a single pixel basis. Spat Vis. 1997;10(4):369–377. Describes bit-stealing, which reaches an effective luminance resolution of 11–12 bits from an 8-bit colour display by trading small amounts of chromatic precision — used in psychophysics whenever sub-1/256 luminance steps are needed. PubMed.

  4. SMPTE ST 2084:2014. High Dynamic Range Electro-Optical Transfer Function of Mastering Reference Displays. Defines the Perceptual Quantizer (PQ) transfer function used by HDR10 and Dolby Vision, referenced in the HDR section. (Paywalled standard with no stable free full-text URL, so cited without a link.)

  5. Bach M. The Freiburg Visual Acuity test—automatic measurement of visual acuity. Optom Vis Sci. 1996;73(1):49–53. The original paper describing FrACT, an automated computer-based visual test; later FrACT documentation added the display-gamma, luminance, and dithering calibration considerations that remote vision tests still build on. PubMed.

  6. Sharpe LT, Stockman A, Jagla W, Jägle H. A luminous efficiency function, V*(λ), for daylight adaptation. J Vis. 2005;5(11):948–968. A modern photopic luminous efficiency function built from the Stockman & Sharpe cone fundamentals — a basis for quantitative use of "luminance" in vision science. PubMed.

Frequently asked questions

Because sRGB, the color standard nearly every screen uses, doesn't map pixel values to luminance linearly. Code value 128 actually emits about 22% of your screen's maximum brightness, not 50% — but it still looks like middle gray because human vision compresses brightness in a roughly logarithmic way, and the sRGB curve is built around that.

Because RGB values are perceptually-coded, not physical luminance. A '5% contrast' step defined as a raw pixel delta corresponds to a different physical (Michelson) contrast depending on the display's gamma curve, so the same nominal number means different things on different screens. Measuring real contrast requires converting to linear-light space first.

Yes. LCDs have limited contrast ratios (1000:1 to 1500:1) because backlight bleeds through even a fully closed shutter, but their gamma is smooth and predictable. OLEDs have true blacks but often show non-monotonic, step-like behavior at very low luminance, which can actually make them worse for testing near-threshold contrast. HDR mode uses entirely different transfer functions and should be turned off for a calibrated test.

Because a test that doesn't calibrate for your specific display's gamma, peak luminance, and viewing conditions is effectively measuring your screen and room, not your eyes. Factors like display gamma, peak luminance, OS color filters, ambient light, and browser zoom can all shift the physical contrast presented by a factor of two or more.

Contrast Screen team
Open-methodology vision-science notes.