How it worksImplementation
The maths behind the picturesSimulation method
Every simulated image on this site runs the same transform: a model published by Machado, Oliveira and Fernandes in 2009. It is the standard one, and it is not the interesting part. The interesting part is where it gets applied.All simulations apply the Machado, Oliveira and Fernandes (2009) physiologically-based model for colour vision deficiency, IEEE TVCG 15(6), 1291-1298. The model itself is conventional. The working colour space is where implementations diverge.
It runs in linear light, and most do notWorking space: linear RGB
The model is built from how cone cells respond to light, and cone responses live in linear light. But the numbers in an image file are not linear: they are gamma-encoded, bent by a curve so that dark tones get more of the available range. Multiply the bent numbers and you get an answer that looks plausible and is wrong.The model derives from cone spectral sensitivities, which are defined in linear light. Image data is gamma-encoded, so applying the matrix directly to encoded values computes on a non-linear representation. The result is systematically incorrect while remaining visually plausible.
So every pixel is decoded to linear light first, transformed, then re-encoded on the way out. The decode uses the real piecewise curve from the sRGB standard, not the 2.2 shortcut, because the two disagree most in exactly the dark tones where the shortcut is easiest to get away with.Pixels are decoded with the piecewise IEC 61966-2-1 transfer function, transformed, and re-encoded. The 2.2 power approximation is not used: it diverges from the standard curve most in the low-luminance region, where the error is least visible and therefore least likely to be caught.
A review of open-source colorblindness simulators by DaltonLens found missing sRGB decoding to be the common bug in existing versions of this model. That is the step this site is careful about.DaltonLens, in a published review of open-source CVD simulation code, identifies absent sRGB decoding as the prevailing defect across existing implementations of this model.
Where the numbers come fromMatrix provenance
The paper publishes a 3x3 matrix for each type at eleven severities, from nothing at all to the full dichromatic case. All 297 of those numbers were taken from the authors own published page, and a test in this repo compares every one of them against a separate transcription from a different source. If the two ever disagree, the build stops.The model specifies a row-major 3x3 matrix per deficiency type at eleven severity steps spanning 0.0 to 1.0. All 297 coefficients are transcribed from the authors published table, and cross-validated against an independent transcription by tests/matrices.test.mjs. Divergence fails the build.
Severities in between the published steps are interpolated between the two nearest matrices. Severity zero is the identity, so a visitor with typical vision is never shown a mangled picture, and complete achromatopsia is refused outright rather than faked with a greyscale filter.Intermediate severities are linearly interpolated between adjacent published matrices. Severity 0.0 is asserted to be the identity transform. Achromatopsia uses Rec. 709 luminance weights and is handled as a distinct case rather than approximated.
Two code paths, held to the same answerPath equivalence
Photographs are transformed in JavaScript, pixel by pixel. The page itself, the wall behind everything, is transformed by an SVG filter in the browser instead, because that is the only way to shift a whole live document. Those are two separate pieces of code that must agree, so a test asserts they do.Raster content is transformed in JavaScript; document chrome is transformed via an SVG feColorMatrix, which is the only mechanism able to filter live DOM. Both derive from one constant and one matrix source, and a test asserts numerical agreement between the two paths.
Where this model is weakKnown limitations
Machado 2009 is here for one good reason: it is the only model that seriously tries to render anomalous trichromacy, which is the common case and most of what this site shows. Almost everything else simulates full dichromacy and then fades it toward the original photo, which is a crossfade rather than a model. That choice has a cost, and it is only fair to say what it is.This model is used because it is the only published approach that derives anomalous trichromacy directly rather than interpolating between normal vision and the dichromatic case. That advantage does not extend uniformly across the conditions it covers.
At the very top of the severity slider, and in the two dichromatic rows on the reference page, this model is running past where it is strongest. The same DaltonLens review cited above recommends it for anomalous trichromacy and specifically not for full dichromacy, where two older models, Brettel 1997 and Vienot 1999, are better validated. Those cases are rare, and this site is built around the argument that they are rare, so it keeps one model throughout rather than splicing a second one onto the end of a slider. That is a deliberate trade and not an oversight.At severity 1.0, and in the deuteranopia and protanopia rows on the reference page, the model is applied outside the regime its own reviewers endorse. DaltonLens recommends Machado 2009 for anomalous trichromacy but not for full dichromacy, where Brettel 1997 and Vienot 1999 have stronger validation. A single continuous model is retained here in preference to a discontinuity at the top of the severity range.
The blue-yellow transform is the least sure part of all of this. Brettel 1997 is the model people trust for it, and this one is not that. Blue-yellow colorblindness is rare, and the site already says a result pointing that way is worth a real optometrist rather than a web page, which is advice worth taking twice over here.The tritan matrices are the least validated component of this model. Brettel 1997 remains the reference method for tritanopia. Given the low prevalence of tritan defects and the possibility of an acquired cause, a tritan result warrants clinical assessment regardless of what this simulation renders.
Check it yourselfVerification
None of the above is worth much as a promise. The transform, the matrices and the tests that hold them honest are all readable, and the claims on this page each have a test behind them rather than an assurance.These claims are individually testable. The transform, matrix tables and their validating tests are readable, and each assertion on this page corresponds to a named test rather than a statement of intent.
Machado, G. M., Oliveira, M. M., and Fernandes, L. A. F. (2009). A Physiologically-based Model for Simulation of Color Vision Deficiency. IEEE Transactions on Visualization and Computer Graphics, 15(6), 1291-1298.Machado, G. M., Oliveira, M. M., & Fernandes, L. A. F. (2009). A Physiologically-based Model for Simulation of Color Vision Deficiency. IEEE TVCG, 15(6), 1291-1298. doi:10.1109/TVCG.2009.113