Class ColorAnalysis
Perceptual color measurement: WCAG 2.x relative luminance and contrast ratio, Oklab delta-E perceptual distance, and correlated color temperature (CCT) estimation via McCamy's 1992 polynomial approximation.
Inherited Members
Namespace: Scylla.Core.Util
Assembly: ScyllaCore.dll
Syntax
public static class ColorAnalysis
Remarks
All methods accept Unity UnityEngine.Color values in sRGB (the Unity default). Methods that require linear-light or XYZ arithmetic convert internally using SRGBToLinear(float) and convert back before returning, so callers do not need to perform any color-space pre-processing. Alpha is ignored throughout.
RelativeLuminance(Color) is deliberately not the same
calculation as GetLuminance(Color). This class
linearizes each channel first, as WCAG requires, while
GetLuminance weights the gamma-encoded values directly. The two
return different numbers for the same input and both are correct for
their own purpose; use this one for any accessibility decision.
Use this together with ColorBlindnessSimulator to check that a palette stays legible for players with a color vision deficiency, and with ColorRamps to derive variants that hold a contrast target.
Methods
EstimateCCT(Color)
Estimates the correlated color temperature of a color in Kelvin, using McCamy's 1992 cubic approximation.
Declaration
public static float EstimateCCT(Color color)
Parameters
| Type | Name | Description |
|---|---|---|
| Color | color | The color to measure. Alpha is ignored. |
Returns
| Type | Description |
|---|---|
| float | The estimated temperature in Kelvin, within |
Remarks
The color is converted to CIE XYZ with the sRGB D65 matrix, reduced
to CIE xy chromaticity, and fed through the polynomial
CCT = 449n^3 + 3525n^2 + 6823.3n + 5520.33, where
n = (x - 0.3320) / (0.1858 - y).
The approximation is only meaningful for colors near the Planckian locus. Colors far from it, and pure saturated hues in particular, have no sensible color temperature, so the method returns 0 rather than a misleading number. Treat a zero result as "off-locus" and not as a temperature.
MeetsWCAG(float, WCAGLevel, bool)
Tests whether a contrast ratio meets the threshold for a conformance level and text size.
Declaration
public static bool MeetsWCAG(float ratio, WCAGLevel level, bool largeText = false)
Parameters
| Type | Name | Description |
|---|---|---|
| float | ratio | A contrast ratio, normally from WCAGContrast(Color, Color). |
| WCAGLevel | level | The conformance level to test against. |
| bool | largeText | Whether the relaxed large-scale threshold applies. |
Returns
| Type | Description |
|---|---|
| bool |
|
Remarks
Thresholds are 4.5 for AA standard text, 3.0 for AA large text and graphical elements, 7.0 for AAA standard text, and 4.5 for AAA large text. Large-scale text means at least 18 point, or 14 point bold.
Pass true for largeText when checking a
heading, an icon, a focus ring, or a control border, all of which
the guidelines treat under the relaxed threshold.
OklabDeltaE(Color, Color)
Calculates the perceptual distance between two colors as the Euclidean distance in Oklab space.
Declaration
public static float OklabDeltaE(Color a, Color b)
Parameters
| Type | Name | Description |
|---|---|---|
| Color | a | The first color. Alpha is ignored. |
| Color | b | The second color. Alpha is ignored. |
Returns
| Type | Description |
|---|---|
| float | The Oklab distance. Zero for identical colors. |
Remarks
Oklab is perceptually uniform, so a given numeric difference corresponds to roughly the same perceived difference anywhere in the space. That is what makes this a better separation test than comparing RGB channels.
As a rough scale: below 0.01 is imperceptible, below 0.03 is very subtle, below 0.06 is subtle, below 0.10 is noticeable, below 0.20 is distinct, and above that is a strong difference.
RelativeLuminance(Color)
Calculates the WCAG 2.x relative luminance of a color: the perceived brightness of the color on a scale where black is 0 and white is 1.
Declaration
public static float RelativeLuminance(Color color)
Parameters
| Type | Name | Description |
|---|---|---|
| Color | color | The color to measure. Alpha is ignored. |
Returns
| Type | Description |
|---|---|
| float | The relative luminance in the range |
Remarks
Each channel is converted from sRGB to linear light first, then
weighted by the Rec. 709 coefficients
0.2126R + 0.7152G + 0.0722B. The linearization step is what
separates this from GetLuminance(Color),
and it is required for any accessibility calculation.
WCAGContrast(Color, Color)
Calculates the WCAG 2.x contrast ratio between two colors.
Declaration
public static float WCAGContrast(Color foreground, Color background)
Parameters
| Type | Name | Description |
|---|---|---|
| Color | foreground | The foreground color, typically text or an icon. |
| Color | background | The background color the foreground sits on. |
Returns
| Type | Description |
|---|---|
| float | The contrast ratio in the range |
Remarks
The ratio is (Llighter + 0.05) / (Ldarker + 0.05), where each
L is a RelativeLuminance(Color). The result ranges
from 1 (identical luminance) to 21 (black against white). The order
of the arguments does not matter.
Compare the result against a threshold with MeetsWCAG(float, WCAGLevel, bool) rather than hardcoding a number at the call site.