混合混合模式饱和度来自哪个色彩空间?

What colorspace is mix-blend-mode saturation from?

The spec for blend-mode saturation 说:

Creates a color with the saturation of the source color and the hue and luminosity of the backdrop color.

最初我认为它会是 HSL,因为这是唯一可以在具有饱和通道的 Web 开发中使用的颜色space,但显然不是这样:

.color {
  width: 100px;
  height: 100px;
}

.expected-color {
  background: hsl(270, 25%, 50%);
}

.backdrop-color {
  background: hsl(270, 85%, 50%);
}

.source-color {
  mix-blend-mode: saturation;
  background: hsl(45, 25%, 50%);
}
Expected
<div class="color expected-color"></div>

Actual
<div class="color backdrop-color">
  <div class="color source-color"></div>
</div>

演示 HSV/HSB 并不容易,但我使用颜色转换器(例如 link)进行的测试表明它也不是那种颜色 space。

.color {
  width: 100px;
  height: 100px;
}

.expected-color {
  /* HSB/HSV - 270, 25, 50 */
  background: #706080;
}

.backdrop-color {
  /* HSB/HSV - 270, 85, 50 */
  background: #491380;
}

.source-color {
  /* HSB/HSV - 45, 25, 50 */
  mix-blend-mode: saturation;
  background: #807860;
}
Expected
<div class="color expected-color"></div>

Actual
<div class="color backdrop-color">
  <div class="color source-color"></div>
</div>

与 LCH (converter) 一样,它没有饱和通道,但它的色度通道实际上是饱和度的模拟:

.color {
  width: 100px;
  height: 100px;
}

.expected-color {
  /* LCH - 50, 25, 270 */
  background: rgb(90,121,161);
}

.backdrop-color {
  /* LCH - 50, 85, 270 */
  background: rgb(0,125,255);
}

.source-color {
  /* LCH - 50, 25, 45 */
  mix-blend-mode: saturation;
  background: rgb(157,107,90);
}
Expected
<div class="color expected-color"></div>

Actual
<div class="color backdrop-color">
  <div class="color source-color"></div>
</div>

似乎在 Edge、Chrome 和 Firefox 中是一致的。

那么mix-blend-mode: saturation定义的是什么颜色space?还是我误解了它的工作原理?

我做了一些(很多)更多的挖掘,看起来他们使用的数学是不同颜色space与一般颜色理论相结合的奇怪组合:

规范中描述的饱和函数是:

B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))

其中Cb是背景颜色,Cs是源颜色;在 sRGB space 中(仅表示 RGB[0 - 1] 范围内)。

其中使用的函数定义为:

    ClipColor(C)
        L = Lum(C)
        n = min(Cred, Cgreen, Cblue)
        x = max(Cred, Cgreen, Cblue)
        if(n < 0)
            C = L + (((C - L) × L) / (L - n))

        if(x > 1)
            C = L + (((C - L) × (1 - L)) / (x - L))

        return C

    Lum(C) = 0.3 x Cred + 0.59 x Cgreen + 0.11 x Cblue

    SetLum(C, l)
        d = l - Lum(C)
        Cred = Cred + d
        Cgreen = Cgreen + d
        Cblue = Cblue + d
        return ClipColor(C)

    Sat(C) = max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue)

    SetSat(C, s)
        if(Cmax > Cmin)
            Cmid = (((Cmid - Cmin) x s) / (Cmax - Cmin))
            Cmax = s
        else
            Cmid = Cmax = 0
        Cmin = 0
        return C;

我们可以忽略 ClipColorSetX 函数,因为我们真的只对确定颜色 space(s)(如果有)感兴趣。剩下:

Lum(C) = 0.3 x Cred + 0.59 x Cgreen + 0.11 x Cblue

Sat(C) = max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue)

什么是 Lum

函数的名称及其用法可能让您假设它们指的是有时归因于 HSL 中的 LB 的亮度或 HSB/HSV 中的 V。他们不是。此函数用于确定人眼颜色的相对亮度。它来自 YIQ colorspace:

请注意,第一行 - 将映射到 Y(亮度)值 - 与 Lum(C) 公式中的幻数完美匹配(尽管稍微更精确)。

对比一下:

HSB/HSV 中的 B/V 频道是 Max(R,G,B)

HSL 中的 L 频道是 ( Max(R,G,B) - Min{R,G,B) ) / 2

什么是 Sat

这显然是(某种程度上的)饱和度,但它不是来自任何特定颜色space。它更像是您如何看待 RGB 颜色 space 中的饱和度的抽象。第一个建议认为这是一种考虑饱和度的方法似乎来自 this 2003 paper,这主要是对当时的现有颜色 space 的批评,以及使用一种未使用过的颜色的建议space IHLS.

对比:

S in HSB/HSV( Max(R,G,B) - Min(R,G,B) ) / Max(R,G,B)0 如果 Max(R,G,B)0.

如果 L10HSL 中的

S( Max(R,G,B) - L ) / Min(L, 1 - L)0。 (与上面定义的 L 相同)。


我能从这一切中得出的唯一结论是 mix-blend-mode: saturation 与颜色 space 完全无关,而更多地与更一般意义上的“饱和度”有关;同样,mix-blend-mode: luminosity 不一定与任何特定颜色有关space,而是作为一种保持“亮度感知”的方式。

如果我们 指出最有可能的候选人,那就是 YIQ 颜色space,我没有在深入研究之前听说过。规范中使用的 Saturation 的过度简化可以称为 Chrominance 的度量,这就是 IQ 渠道集体代表。

对于软件开发人员来说,这些混合模式的命名似乎不可避免地含糊不清,因为它们的目标受众可能是设计师,而不是工程师。

不是我想要的答案,但它似乎是答案。

更新

我刚刚与该规范的一位编辑(作者?)进行了一次有趣的交流。这种混乱的理由是(换句话说)“Adobe 产品在过去 20 年里一直这样做,人们已经习惯了”。显然没有必要过多地质疑这种推理的不当压力,但我的印象是该规范主要是对 photoshop 等现有混合模式的复制粘贴。