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.
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 spatial dithering (Allard & Faubert, 2008) and Tyler's bit-stealing, which trades a tiny bit of chromatic precision for ~11–12 effective bits of luminance resolution (Tyler, 1997).
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 are 1000:1 to 1500:1, so black is 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 — PQ (SMPTE ST 2084) or HLG — designed for wider dynamic range. 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 Acuity and Contrast Test was among the first browser-deliverable visual tests to spell out display calibration as a precondition for valid thresholds (Bach, 1996). 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 (Allard & Faubert, 2008). The modern reference function for photopic luminance — V*(λ), the linear combination of cone fundamentals that defines "what counts as bright" for a calibrated observer — was nailed down by Sharpe, Stockman, Jagla & Jägle (2005), and is still the basis for any test that wants to claim it's measuring 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.
References
- Allard, R., & Faubert, J. (2008). The noisy-bit method for digital displays: converting a 256 luminance resolution into a continuous resolution. Behavior Research Methods, 40(3), 735–743. Validates the spatial-dithering approach used to render sub-1/256 contrast steps cleanly on 8-bit displays without biasing contrast thresholds.
- Bach, M. (1996). The Freiburg Visual Acuity Test — automatic measurement of visual acuity. Optometry and Vision Science, 73(1), 49–53. The original FrACT paper; subsequent FrACT documentation laid out browser-display gamma, dithering, and per-device calibration considerations that remote vision tests still build on.
- Sharpe, L. T., Stockman, A., Jagla, W., & Jägle, H. (2005). A luminous efficiency function, V*(λ), for daylight adaptation. Journal of Vision, 5(11):3, 948–968. Modern reference for the photopic luminous efficiency function, defined as a linear combination of the Stockman & Sharpe cone fundamentals — the basis for any quantitative use of "luminance" in vision science.
- Tyler, C. W. (1997). Colour bit-stealing to enhance the luminance resolution of digital displays on a single pixel basis. Spatial Vision, 10(4), 369–377. Original description of the bit-stealing technique that yields ~11–12 bits of effective luminance resolution from an 8-bit colour display by trading small amounts of chromatic precision — used in modern psychophysics whenever sub-1/256 luminance steps are needed.
Standards
- IEC 61966-2-1:1999. Multimedia systems and equipment — Colour measurement and management — Part 2-1: Default RGB colour space — sRGB. Normative specification of the sRGB colour space, including the piecewise transfer function approximated throughout this post as a 2.2 power gamma.
- SMPTE ST 2084:2014. High Dynamic Range Electro-Optical Transfer Function of Mastering Reference Displays. The Perceptual Quantizer (PQ) transfer function used by HDR10 and Dolby Vision, referenced in the HDR section.