somethinglikegames.de

Categories


Tags

Opacity

After my first article on blending-modes, the topic somehow stuck with me, so I got pulled down the associated rabbit hole. To process my experiences on the journey back to reality, I created an “almighty” 😉 node for blending layers. It contains 47 different blending modes for grayscale and RGB(A) and three additional blending modes specifically for NormalMaps. However, so that you don’t lose track of how the various blending modes work, the rest of the article is intended as a reference work.

About UberBlend

I named the node UberBlend because I have never come across such a complete collection of blending modes before. Are so many blending modes really necessary? Probably not, but why not try them out to achieve better results. My aim is to increase the probability of “happy accidents”.

UberBlend is available in different versions. Once as an all-in-one node “UberBlend” and once divided into “UberBlend Grayscale”, “UberBlend Color” and “UberBlend Normals”. The reason for this is that custom nodes in Adobe Substance 3D Designer are subject to certain limitations, so unfortunately I can’t offer the best user experience with the all-in-one solution. The limitation is that you have to manually choose between grayscale and color, because I unfortunately haven’t found a way to take over the convenience of the integrated blend node, where the color mode is based on the background input. As a result, you can get two additional inputs when switching between Grayscale and Color if you have already connected the inputs of the previously selected color mode.

What functionalities does UberBlend generally offer?

  • 47 different general blending modes; more details can be found in the next section
  • 3 special blending modes for NormalMaps
  • “Advanced” mode for RGB(A) inputs, in which settings can be made per color channel
  • Familiar functionalities of the integrated blend node, such as support for input masks, setting the opacity, …

I am currently planning to create versions of UberBlend that can be used with Substance 3D Painter and Photoshop. Since both have their own challenges, these versions will be released separately.

For the impatient: Click here to download

Blending-Modes

The following table provides a comparison of the different blending modes:

  • In the Brightness column, you can see the blend result of the two known grayscale gradients, with the horizontal gradient acting as the background and the vertical gradient as the foreground.
  • In the Brightness difference column, you can see the changes in brightness between the blend result and the original background. Lightenings are reddish and darkenings are colored bluish. Greenish areas have little or no change.
  • The table is sorted alphabetically. If anyone has an idea for a better sorting, please let me know.
Blending ModeBrightnessBrightness difference
Arctan\(p_\text{new} = 2\pi * \text{arctan}(\frac{p_\text{bg}}{p_\text{fg}})\)
Helligkeitsveränderungen von ArctanHelligkeitsunterschiede von Arctan
Average\(p_\text{new} = \frac{p_\text{fg} + p_\text{bg}}{2}\)
Helligkeitsveränderungen von AverageHelligkeitsunterschiede von Average
Bleach\(p_\text{new} = (1 - p_\text{fg}) + (1 - p_\text{bg}) - 1\)
Helligkeitsveränderungen von BleachHelligkeitsunterschiede von Bleach
Bright\(p_\text{new} = 1 - \text{Dark}(1 - p_\text{fg}, 1 - p_\text{bg})\)
Helligkeitsveränderungen von BrightHelligkeitsunterschiede von Bright
Burn\(p_\text{new} = 1 - \frac{1 - p_\text{fg}}{p_\text{bg}}\)
Helligkeitsveränderungen von BurnHelligkeitsunterschiede von Burn
Burn (Reverse)\(p_\text{new} = 1 - \frac{1 - p_\text{bg}}{p_\text{fg}}\)
Helligkeitsveränderungen von Burn (Reverse)Helligkeitsunterschiede von Burn (Reverse)
Burn (Soft)\(p_\text{new} = \begin{cases} \frac{1}{2} * \frac{p_\text{fg}}{1 - p_\text{bg}} & p_\text{bg} + p_\text{fg} \lt 1 \\\\1 - (\frac{1}{2} * \frac{1 - p_\text{bg}}{p_\text{fg}}) & \text{sonst}\end{cases} \)
Helligkeitsveränderungen von Burn (Soft)Helligkeitsunterschiede von Burn (Soft)
Dark\(p_\text{new} = p_\text{bg}p_\text{fg} + p_\text{fg} - p_\text{fg}^2 \)
Helligkeitsveränderungen von DarkHelligkeitsunterschiede von Dark
Darken / Min\(p_\text{new} = \text{Min}(p_\text{bg}, p_\text{fg})\)
Helligkeitsveränderungen von Darken / MinHelligkeitsunterschiede von Darken / Min
Darken (Illusions.hu)\(p_\text{new} = \log_2(1 + \frac{\frac{p_\text{bg}}{1- p_\text{fg}}}{8})\)
Helligkeitsveränderungen von Darken (Illusions.hu)Helligkeitsunterschiede von Darken (Illusions.hu)
Difference\(p_\text{new} = |p_\text{bg} - p_\text{fg}|\)
Helligkeitsveränderungen von DifferenceHelligkeitsunterschiede von Difference
Divide\(p_\text{new} = \frac{p_\text{bg}}{p_\text{fg}}\)
Helligkeitsveränderungen von DivideHelligkeitsunterschiede von Divide
Dodge\(p_\text{new} = \frac{p_\text{bg}}{1 - p_\text{fg}}\)
Helligkeitsveränderungen von DodgeHelligkeitsunterschiede von Dodge
Dodge (Linear) / Add\(p_\text{new} = p_\text{bg} + p_\text{fg}\)
Helligkeitsveränderungen von Dodge (Linear) / AddHelligkeitsunterschiede von Dodge (Linear) / Add
Dodge (Reverse)\(p_\text{new} = \frac{p_\text{fg}}{1 - p_\text{bg}}\)
Helligkeitsveränderungen von Dodge (Reverse)Helligkeitsunterschiede von Dodge (Reverse)
Dodge (Soft)\(p_\text{new} = \begin{cases} \frac{1}{2} * \frac{p_\text{bg}}{1 - p_\text{fg}} & p_\text{bg} + p_\text{fg} \lt 1 \\\\1 - (\frac{1}{2} * \frac{1 - p_\text{fg}}{p_\text{bg}}) & \text{sonst}\end{cases} \)
Helligkeitsveränderungen von Dodge (Soft)Helligkeitsunterschiede von Dodge (Soft)
Exclusion\(p_\text{new} = p_\text{bg} + p_\text{fg} - 2 p_\text{bg} p_\text{fg}\)
Helligkeitsveränderungen von ExclusionHelligkeitsunterschiede von Exclusion
Freeze\(p_\text{new} = 1 - (1 - p_\text{bg}) \frac{1 - p_\text{bg}}{p_\text{fg}}\)
Helligkeitsveränderungen von FreezeHelligkeitsunterschiede von Freeze
Gamma (Bright)\(p_\text{new} = 1 - (1 - p_\text{bg}) ^ \frac{1}{1 - p_\text{fg}}\)
Helligkeitsveränderungen von Gamma (Bright)Helligkeitsunterschiede von Gamma (Bright)
Gamma (Dark)\(p_\text{new} = p_\text{bg} ^ \frac{1}{p_\text{fg}}\)
Helligkeitsveränderungen von Gamma (Dark)Helligkeitsunterschiede von Gamma (Dark)
Gamma (Light)\(p_\text{new} = p_\text{bg} ^ {p_\text{fg}}\)
Helligkeitsveränderungen von Gamma (Light)Helligkeitsunterschiede von Gamma (Light)
Geometric Mean\(p_\text{new} = \sqrt{p_\text{bg} p_\text{bg}}\)
Helligkeitsveränderungen von Geometric MeanHelligkeitsunterschiede von Geometric Mean
Glow\(p_\text{new} = \frac{p_\text{fg} p_\text{fg}}{p_\text{bg}}\)
Helligkeitsveränderungen von GlowHelligkeitsunterschiede von Glow
Grain (Extract)\(p_\text{new} = p_\text{bg} + (1 - p_\text{fg}) - \frac{1}{2}\)
Helligkeitsveränderungen von Grain (Extract)Helligkeitsunterschiede von Grain (Extract)
Grain (Merge)\(p_\text{new} = p_\text{bg} + p_\text{fg} - \frac{1}{2}\)
Helligkeitsveränderungen von Grain (Merge)Helligkeitsunterschiede von Grain (Merge)
Heat\(p_\text{new} = 1 - (1 - p_\text{fg}) \frac{1 - p_\text{fg}}{p_\text{bg}}\)
Helligkeitsveränderungen von HeatHelligkeitsunterschiede von Heat
Lighten / Max\(p_\text{new} = \text{Max}(p_\text{bg}, p_\text{fg})\)
Helligkeitsveränderungen von Lighten / MaxHelligkeitsunterschiede von Lighten / Max
Light (Hard)\(p_\text{new} = \begin{cases} 2 p_\text{bg} p_\text{fg} & p_\text{fg} \lt \frac{1}{2} \\\\1 - (2 * (1 - p_\text{fg})(1 - p_\text{bg})) & \text{sonst}\end{cases} \)
Helligkeitsveränderungen von Light (Hard)Helligkeitsunterschiede von Light (Hard)
Lighten (Illusions.hu)\(p_\text{new} = 1 - \text{Darken (Illusions.hu)}(1 - p_\text{fg}, 1 - p_\text{bg})\)
Helligkeitsveränderungen von Lighten (Illusions.hu)Helligkeitsunterschiede von Lighten (Illusions.hu)
Light (Linear) / Add Sub\(p_\text{new} = p_\text{bg} + ((p_\text{fg} - \frac{1}{2}) * 2)\)
Helligkeitsveränderungen von Light (Linear) / Add SubHelligkeitsunterschiede von Light (Linear) / Add Sub
Light (Pin)\(p_\text{new} = \begin{cases} \text{Min}(p_\text{bg}, 2 p_\text{fg}) & p_\text{fg} \lt \frac{1}{2} \\\\\text{Max}(p_\text{bg}, 2 p_\text{fg} - 1) & \text{sonst}\end{cases}\)
Helligkeitsveränderungen von Light (Pin)Helligkeitsunterschiede von Light (Pin)
Light (Vivid)\(p_\text{new} = \begin{cases} \text{Burn}(p_\text{bg}, 2 p_\text{fg}) & p_\text{fg} \lt \frac{1}{2} \\\\\text{Dodge}(p_\text{bg}, 2 p_\text{fg} - 1) & \text{sonst}\end{cases}\)
Helligkeitsveränderungen von Light (Vivid)Helligkeitsunterschiede von Light (Vivid)
Multiply\(p_\text{new} = p_\text{bg} * p_\text{fg}\)
Helligkeitsveränderungen von MultiplyHelligkeitsunterschiede von Multiply
Negation\(p_\text{new} = 1 - |(1 - p_\text{bg}) - p_\text{fg}|\)
Helligkeitsveränderungen von NegationHelligkeitsunterschiede von Negation
Overlay\(p_\text{new} = \begin{cases} 2 p_\text{bg} p_\text{fg} & p_\text{bg} \lt \frac{1}{2} \\\\1 - (2 (1 - p_\text{bg}) (1 - p_\text{fg})) & \text{sonst}\end{cases}\)
Helligkeitsveränderungen von OverlayHelligkeitsunterschiede von Overlay
Parallel\(p_\text{new} = \frac{2}{\frac{1}{p_\text{bg}}+\frac{1}{p_\text{fg}}}\)
Helligkeitsveränderungen von ParallelHelligkeitsunterschiede von Parallel
Phoenix\(p_\text{new} = \text{Min}( p_\text{bg}, p_\text{fg}) + (1 - \text{Max}(p_\text{bg}, p_\text{fg}))\)
Helligkeitsveränderungen von PhoenixHelligkeitsunterschiede von Phoenix
Reflect\(p_\text{new} = \frac{p_\text{bg} ^ 2}{1 - p_\text{fg}}\)
Helligkeitsveränderungen von ReflectHelligkeitsunterschiede von Reflect
Screen\(p_\text{new} = p_\text{bg} + p_\text{fg} - p_\text{bg} * p_\text{fg}\)
Helligkeitsveränderungen von ScreenHelligkeitsunterschiede von Screen
Shadow\(p_\text{new} = 1 - ((1 - p_\text{bg}) p_\text{fg}) + \sqrt{1 - p_\text{fg}} \)
Helligkeitsveränderungen von ShadowHelligkeitsunterschiede von Shadow
Softlight (PS, DS)\(p_\text{new} = \begin{cases} 2 p_\text{bg} p_\text{fg} + p_\text{bg}^2 (1 - 2 p_\text{fg}) & p_\text{fg} \lt 0.5 \\\sqrt{p_\text{bg}} (2 p_\text{fg} - 1) + 2 p_\text{bg} (1 - p_\text{fg}) & \text{sonst}\end{cases}\)
Helligkeitsveränderungen von Softlight (PS, DS)Helligkeitsunterschiede von Softlight (PS, DS)
Softlight (Illusions.hu)\(p_\text{new} = p_\text{bg} ^ {(2 ^ {2 (0,5 - p_\text{fg} )})}\)
Helligkeitsveränderungen von Softlight (Illusions.hu)Helligkeitsunterschiede von Softlight (Illusions.hu)
Softlight (PegTop)\(p_\text{new} = (1 - 2 p_\text{fg}) * p_\text{bg} ^ 2 + 2 p_\text{bg} p_\text{fg} \)
Helligkeitsveränderungen von Softlight (PegTop)Helligkeitsunterschiede von Softlight (PegTop)
Subtract\(p_\text{new} = p_\text{bg} - p_\text{fg}\)
Helligkeitsveränderungen von SubtractHelligkeitsunterschiede von Subtract

Even though blending of NormalMaps only rarely occurs within Substance 3D Designer, I thought that it might not hurt to integrate specialized blending modes. For this reason, I followed the really detailed and interesting article Blending in Detail and transferred the three “best” blending modes, i.e. whiteout blending, UDN blending and reoriented normal mapping.

The following two normal maps are used as test objects:

Basis / Background

Basis / Background

Detail / Foreground

Detail / Foreground

I have been thinking for a long time about how I can also write the respective NormalMap calculations as a formula. I hope I have found a comprehensible way. The shader-oriented variant can be found in the linked article Blending in Detail.

Blending ModeFormulaResult
UDN\(\begin{align*} \vec{p_\text{bg}} &= \vec{p_\text{bg}} * 2 - 1 \\ \vec{p_\text{fg}} &= \vec{p_\text{fg}} * 2 - 1 \\ \vec{r} &= \begin{pmatrix} \vec{p_\text{bg}}_x + \vec{p_\text{fg}}_x \\ \vec{p_\text{bg}}_y + \vec{p_\text{fg}}_y \\ \vec{p_\text{bg}}_z \end{pmatrix} \\ \vec{p_\text{new}} &= \frac{\vec{r}}{|\vec{r}|} * \frac{1}{2} + \frac{1}{2} \end{align*} \)UDN
Whiteout\(\begin{align*} \vec{p_\text{bg}} &= \vec{p_\text{bg}} * 2 - 1 \\ \vec{p_\text{fg}} &= \vec{p_\text{fg}} * 2 - 1 \\ \vec{r} &= \begin{pmatrix} \vec{p_\text{bg}}_x + \vec{p_\text{fg}}_x \\ \vec{p_\text{bg}}_y + \vec{p_\text{fg}}_y \\ \vec{p_\text{bg}}_z * \vec{p_\text{fg}}_z \end{pmatrix} \\ \vec{p_\text{new}} &= \frac{\vec{r}}{|\vec{r}|} * \frac{1}{2} + \frac{1}{2} \end{align*} \)Whiteout
Reoriented Normal Mapping\(\begin{align*} \vec{p_\text{bg}} &= \vec{p_\text{bg}} * \begin{pmatrix} 2 \\ 2 \\ 2 \end{pmatrix} + \begin{pmatrix} -1 \\ -1 \\ 0 \end{pmatrix}\\ \vec{p_\text{fg}} &= \vec{p_\text{fg}} * \begin{pmatrix} -2 \\ -2 \\ 2 \end{pmatrix} + \begin{pmatrix} 1 \\ 1 \\ -1 \end{pmatrix}\\ \vec{r} &= \vec{p_\text{bg}} * (\vec{p_\text{bg}} \cdot \vec{p_\text{fg}}) - \vec{p_\text{fg}} * \vec{p_\text{bg}}_z \\ \vec{p_\text{new}} &= \frac{\vec{r}}{|\vec{r}|} * \frac{1}{2} + \frac{1}{2} \end{align*} \)Reoriented Normal Mapping

So, before the download really comes, a direct comparison between the blending modes of the NormalMaps, as the results only show differences if you look directly.

Comparison of the NormalMap blending modes

Comparison of the NormalMap blending modes

UberBlend Download

I make the SBSAR from UberBlend available to all interested parties free of charge under CC0 1.0.

So you can actually do anything legal with it, as long as you don’t make me responsible for any mistakes. However, if you find any mistakes, I would be happy if you let me know so that I can correct them 😉

Further reading

Of course, I didn’t come up with all this information all by myself. Fortunately, there are people who have already prepared a lot of the information so that I could use them as sources. So if you want to find out more about the topic, you are welcome to visit the following pages: