LinearRGB vs sRGB Color Interpolation in SVG
This article explores the technical and visual differences between
linearRGB and sRGB color interpolation modes
in Scalable Vector Graphics (SVG). Understanding how these two color
spaces handle mathematical blending is essential for avoiding unnatural
dark bands in gradients and ensuring physically accurate lighting and
filter effects in web graphics.
Understanding sRGB vs. linearRGB
Color spaces define how color values are represented numerically. The
fundamental difference between sRGB and
linearRGB lies in gamma correction:
- sRGB (Standard RGB): This is a non-linear color space designed to match how human vision perceives brightness. It applies a gamma curve (approximately \(\gamma = 2.2\)), compressing darker tones and expanding lighter ones to maximize perceived dynamic range on standard display hardware.
- linearRGB: This is a linear color space where numerical values correspond directly to physical light intensity. Doubling a numerical value doubles the amount of emitted light.
How Interpolation Differs in SVG
When SVG calculates transitions between two colors—such as inside a
<linearGradient>,
<radialGradient>, or <filter>
primitive—it must mathematically compute intermediate color steps. The
color-interpolation (for gradients/patterns) and
color-interpolation-filters (for filter effects) attributes
determine which color space is used for these calculations.
1. sRGB Interpolation (Non-linear Math)
In sRGB mode, SVG calculates midpoints directly on
gamma-encoded values:
\[\text{Midpoint} = \frac{\text{Value}_1 + \text{Value}_2}{2}\]
Because these values are non-linear, standard averaging fails to represent how light physically mixes. This mathematically flawed calculation leads to an artificial drop in perceived luminance between contrasting or complementary colors, commonly referred to as the “muddy middle” or “dark band” effect (e.g., blending pure red and pure green produces an unnatural dark brownish-yellow instead of a bright yellow).
2. linearRGB Interpolation (Physically Accurate Math)
In linearRGB mode, SVG first converts non-linear sRGB
values into linear light values (de-gamma), computes the intermediate
color steps linearly, and then converts the results back to sRGB for
screen rendering.
This mimics the physical mixing of real-world light rays. As a result, gradients between contrasting colors maintain proper luminance across the entire transition, eliminating unwanted dark zones and producing brighter, smoother blends.
Default Behaviors in SVG Specifications
The SVG specification defines specific defaults for these properties:
- Gradients and Patterns
(
color-interpolation): Defaults tosRGB. Most designers expect standard CSS-style gradient behavior by default. - Filter Effects
(
color-interpolation-filters): Defaults tolinearRGB. Filter operations like<feGaussianBlur>,<feBlend>, and<feLighting>require physically accurate light calculations to produce correct optical effects.
SVG Syntax Example
To control the interpolation method in your SVG markup, apply the corresponding attribute:
<!-- Gradient interpolated in linearRGB to prevent dark bands -->
<linearGradient id="linearBlend" color-interpolation="linearRGB" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#ff0000" />
<stop offset="100%" stop-color="#00ff00" />
</linearGradient>
<!-- Filter explicitly set to sRGB -->
<filter id="customFilter" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="5" />
</filter>Summary of Key Differences
| Feature | sRGB |
linearRGB |
|---|---|---|
| Gamma State | Gamma-corrected (non-linear) | Gamma removed (linear light) |
| Visual Output | Can produce dark, muddy transitions between opposing colors | Produces smooth, bright, physically accurate color blends |
| Computational Cost | Lower (direct value averaging) | Slightly higher (requires gamma conversion steps) |
| SVG Gradient Default | Yes
(color-interpolation="sRGB") |
No |
| SVG Filter Default | No | Yes
(color-interpolation-filters="linearRGB") |