Blend mode

The blend-mode data type defines how colors should blend when elements overlap.

The Maths

Feel free to skip this section. This just introduces the terms/notations that I want to use.

The behind-the-scene math on how to perform color blend can be seen in the compositing and blending spec (created by Adobe people) and in the Adobe blend modes specification. Here, I summarize the key points.

Blending

Blending is how we mix colors. The blending function BB determines how we get the result color CrC_r from the background/bottom color CbC_b and source/top color CsC_s:

Cr=B(Cs,Cb) C_r = B(C_s, C_b)

A blending mode is separable if we can calculate each RGB component of the result color separately (note that we use lowercase cc to denote a component of CC):

cr=B(cs,cb) c_r = B(c_s, c_b)

Composting

Composting is how we "merge" the layers into the final image (taking into account the alpha channels and the blend-color result). The method used is called Porter–Duff composting, which will be out of our discussion.

Consequently, we will also not discuss about alpha channels here.

Color

A color CC is comprised of red, green, and blue components. Each component has a value between 0 and 1 (inclusive):

C=cred,cgreen,cblue C = \langle c_\mathrm{red}, c_\mathrm{green}, c_\mathrm{blue} \rangle

From individual RGB values, we can calculate the saturation and luminosity using these functions:

Sat(C)=max(cred,cgreen,cblue)min(cred,cgreen,cblue) \mathrm{Sat}(C) = \mathrm{max}(c_\mathrm{red}, c_\mathrm{green}, c_\mathrm{blue}) - \mathrm{min}(c_\mathrm{red}, c_\mathrm{green}, c_\mathrm{blue})
Lum(C)=0.3cred+0.59cgreen+0.11cblue \mathrm{Lum}(C) = 0.3 \cdot c_\mathrm{red} + 0.59 \cdot c_\mathrm{green} + 0.11 \cdot c_\mathrm{blue}

Types of Blending Mode

normal

Takes the top color.

Normal(cb,cs)=cs \mathrm{Normal}(c_b, c_s) = c_s

darken

Takes the darkest color for each RGB component.

Darken(cb,cs)=min(cb,cs) \mathrm{Darken}(c_b, c_s) = \mathrm{min}(c_b, c_s)

lighten

Takes the lightest color for each RGB component.

Lighten(cb,cs)=max(cb,cs) \mathrm{Lighten}(c_b, c_s) = \mathrm{max}(c_b, c_s)

multiply

Multiplies the color value for each RGB component.

  • Multiplying with white results in the initial color (akin to multiplying with 1)
  • Multiplying with black results in a black color (akin to multiplying with 0)
Multiply(cb,cs)=cbcs \mathrm{Multiply}(c_b, c_s) = c_b \cdot c_s

screen

Like projecting an image/light (the source color) to a screen (the background color). Mathematically, it inverts the colors, multiplies them, then inverts the result.

  • Screening with white results in a white color ("projecting a bright white light on any screen color results in a white color")
  • Screening with black results in the initial color ("projecting nothing to a screen results in the screen color")
Screen(cb,cs)=1{(1cb)(1cs)} \mathrm{Screen}(c_b, c_s) = 1 - \lbrace (1 - c_b) (1 - c_s) \rbrace

overlay

Overlays the top color to the bottom color, preserving its hightlights and shadows. Equivalent to hard-light, but with the layers swapped.

Overlay(cb,cs)=HardLight(cs,cb) \mathrm{Overlay}(c_b, c_s) = \mathrm{HardLight}(c_s, c_b)

color-dodge

Brightens the bottom color to reflect the top color.

Similar to screen, but it's easier to create a fully lit color (the top color only needs to be as light as the inverse of the bottom color).

ColorDodge(cb,cs)={min(1,cb1cs)if cs<11if cs=1 \mathrm{ColorDodge}(c_b, c_s) = \begin{cases} \mathrm{min}\left(1, \dfrac{c_b}{1-c_s}\right) &\text{if } c_s < 1 \\ 1 &\text{if } c_s = 1 \end{cases}

color-burn

Darkens the backdrop color to reflect the source color.

Similar to multiply, but it's easier to create a black color (the top color only needs to be as dark as the inverse of the bottom color).

ColorBurn(cb,cs)={1min(1,1cbcs)if cs>00if cs=0 \mathrm{ColorBurn}(c_b, c_s) = \begin{cases} 1 - \mathrm{min}\left(1, \dfrac{1-c_b}{c_s}\right) &\text{if } c_s > 0 \\ 0 &\text{if } c_s = 0 \end{cases}

hard-light

Multiplies or screens the colors, depending on the top color value. Similar to shining a harsh spotlight on the bottom color.

HardLight(cb,cs)={Multiply(cb,2cs)if cs0.5Screen(cb,2cs1)if cs>0.5 \mathrm{HardLight}(c_b, c_s) = \begin{cases} \mathrm{Multiply}(c_b, 2c_s) &\text{if } c_s \le 0.5 \\ \mathrm{Screen}(c_b, 2c_s - 1) &\text{if } c_s > 0.5 \end{cases}

soft-light

Darkens or lightens the colors, depending on the top color value. Similar to shining a diffused spotlight on the bottom color.

SoftLight(cb,cs)={cb(12cs)(cb)(1cb)if cs0.5cb+(2cs1)(D(cb)cb)if cs>0 \mathrm{SoftLight}(c_b, c_s) = \begin{cases} c_b - (1-2c_s)(c_b)(1-c_b) &\text{if } c_s \le 0.5 \\ c_b + (2c_s-1)(D(c_b)-c_b) &\text{if } c_s > 0 \end{cases}
D(cb)={((16cb12)cb+4)cbif cb0.25cbif cb>0.25 D(c_b) = \begin{cases} \left(\left(16c_b - 12\right)c_b + 4\right)c_b &\text{if } c_b \le 0.25 \\ \sqrt{c_b} &\text{if } c_b > 0.25 \end{cases}

difference

Substracts the darker color from the lighter color.

  • Painting with white inverts the bottom color
  • Painting with black produces no change
Difference(cb,cs)=cbcs \mathrm{Difference}(c_b, c_s) = |c_b - c_s|

exclusion

Like difference, but with less contrast.

  • Painting with white inverts the bottom color
  • Painting with black produces no change
Exclusion(cb,cs)=cb+cs(2cbcs) \mathrm{Exclusion}(c_b, c_s) = c_b + c_s - (2 \cdot c_b \cdot c_s)

hue

Use the hue (H) of the top color, and the saturation and luminosity of the bottom color.

saturation

Use the saturation (S) of the top color, and the hue and luminosity of the bottom color.

color

Use the hue and saturation (HS) of the top color, and the luminosity of the bottom color.

luminosity

Use the luminosity (L) of the top color, and the hue and saturation of the bottom color.

References