6

Based on the examples in the TikZ manual around page 341, I expected the following code

    \begin{scope}[blend group=overlay]
      \fill [ball color=red] (90:.6) circle (1);
      \fill [ball color=green] (210:.6) circle (1);
      \fill [ball color=blue] (330:.6) circle (1);
    \end{scope}%

to produce something a bit like this (only 'a bit' due to PDF viewer idiosyncrasies):

expected output for filled paths

Instead, I get this:

actual output

Even allowing for viewer weirdness, this is a little unexpected.

Surprisingly, however, I did manage to produce the expected output above by using this code:

    \begin{scope}[blend group=overlay]
      \node [circle, ball color=red, minimum size=20mm] at (90:.6) {};
      \node [circle, ball color=green, minimum size=20mm] at (210:.6) {};
      \node [circle, ball color=blue, minimum size=20mm] at (330:.6) {};
    \end{scope}%

Now, if this was a viewer issue, I would expect to see at least something like the same issue with blended-filled nodes as with blended-filled paths. After all, I assume that my viewer doesn't know the difference between a node and a path. That said, the world is full of strange and nasty surprises, so who knows? For all I know, Okular may have a designed-in liking for nodes and feature a built-in hatred of paths. But it seems prima facie improbable.

So why do I get such different results when filling paths and nodes and can blending of filled paths be corrected?

Here's a side-by-side comparison, just for completeness:

paths vs. nodes

Complete code:

\documentclass[border=10pt,multi,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
    \begin{scope}[blend group=overlay, xshift=35mm]
      \node [circle, ball color=red, minimum size=20mm] at (90:.6) {};
      \node [circle, ball color=green, minimum size=20mm] at (210:.6) {};
      \node [circle, ball color=blue, minimum size=20mm] at (330:.6) {};
    \end{scope}%
    \begin{scope}[blend group=overlay]
      \fill [ball color=red] (90:.6) circle (1);
      \fill [ball color=green] (210:.6) circle (1);
      \fill [ball color=blue] (330:.6) circle (1);
    \end{scope}%
\end{tikzpicture}
\end{document}

For the interested, here is a complete comparison of blend modes listed in the TikZ manual. Note that the names of some modes are incorrect in the manual and are corrected in the code below.

First, filled paths:

filled paths: all modes

Second, filled nodes:

filled nodes: all modes

Code to reproduce:

\documentclass[border=10pt,multi,tikz]{standalone}
\newcommand*\showblend[2][]{% o manual, 314 (gweler hefyd gwestiwn Marcos: http://tex.stackexchange.com/q/248721/)
  \begin{scope}[#1,local bounding box/.expanded=#2]
    \begin{scope}[blend group=#2]
      \fill [ball color=red] (90:.6) circle (1);
      \fill [ball color=green] (210:.6) circle (1);
      \fill [ball color=blue] (330:.6) circle (1);
    \end{scope}%
  \end{scope}%
  \node [below=5mm of #2, anchor=mid] {#2};
}
\newcommand*\shownodeblend[2][]{%
  \begin{scope}[#1,local bounding box/.expanded=#2]
    \begin{scope}[blend group=#2]
      \node [ball color=red, circle, minimum size=20mm] at (90:.6) {};
      \node [ball color=green, circle, minimum size=20mm] at (210:.6) {};
      \node [ball color=blue, circle, minimum size=20mm] at (330:.6) {};
    \end{scope}%
  \end{scope}%
  \node [below=5mm of #2, anchor=mid] {#2};
}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \showblend{normal}
  \showblend[xshift=35mm]{multiply}
  \showblend[xshift=70mm]{screen}
  \showblend[xshift=105mm]{overlay}
  \showblend[xshift=0mm,yshift=-40mm]{darken}
  \showblend[xshift=35mm,yshift=-40mm]{lighten}
  \showblend[xshift=70mm,yshift=-40mm]{color dodge}
  \showblend[xshift=105mm,yshift=-40mm]{color burn}
  \showblend[xshift=0pt,yshift=-80mm]{hard light}
  \showblend[xshift=35mm,yshift=-80mm]{soft light}
  \showblend[xshift=70mm,yshift=-80mm]{difference}
  \showblend[xshift=105mm,yshift=-80mm]{exclusion}
  \showblend[xshift=0pt,yshift=-120mm]{hue}
  \showblend[xshift=35mm,yshift=-120mm]{saturation}
  \showblend[xshift=70mm,yshift=-120mm]{color}
  \showblend[xshift=105mm,yshift=-120mm]{luminosity}
\end{tikzpicture}
\begin{tikzpicture}
  \shownodeblend{normal}
  \shownodeblend[xshift=35mm]{multiply}
  \shownodeblend[xshift=70mm]{screen}
  \shownodeblend[xshift=105mm]{overlay}
  \shownodeblend[xshift=0mm,yshift=-40mm]{darken}
  \shownodeblend[xshift=35mm,yshift=-40mm]{lighten}
  \shownodeblend[xshift=70mm,yshift=-40mm]{color dodge}
  \shownodeblend[xshift=105mm,yshift=-40mm]{color burn}
  \shownodeblend[xshift=0pt,yshift=-80mm]{hard light}
  \shownodeblend[xshift=35mm,yshift=-80mm]{soft light}
  \shownodeblend[xshift=70mm,yshift=-80mm]{difference}
  \shownodeblend[xshift=105mm,yshift=-80mm]{exclusion}
  \shownodeblend[xshift=0pt,yshift=-120mm]{hue}
  \shownodeblend[xshift=35mm,yshift=-120mm]{saturation}
  \shownodeblend[xshift=70mm,yshift=-120mm]{color}
  \shownodeblend[xshift=105mm,yshift=-120mm]{luminosity}
\end{tikzpicture}
\end{document}

The results above are all produced with pdfTeX. However, testing with XeTeX produces the same results.

cfr
  • 198,882

1 Answers1

4

According to pgfmanual (section 2.14 Shading) \shade (instead of \fill) is the way to go:

\documentclass[border=10pt,multi,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
    \begin{scope}[blend group=overlay, xshift=35mm]
      \node [circle, ball color=red, minimum size=20mm] at (90:.6) {};
      \node [circle, ball color=green, minimum size=20mm] at (210:.6) {};
      \node [circle, ball color=blue, minimum size=20mm] at (330:.6) {};
    \end{scope}%
    \begin{scope}[blend group=overlay]
      \shade [ball color=red] (90:.6) circle (1);
      \shade [ball color=green] (210:.6) circle (1);
      \shade [ball color=blue] (330:.6) circle (1);
    \end{scope}%
\end{tikzpicture}
\end{document}

enter image description here

Explanation (cfr)

ball color invokes shade implicitly because it is a shading. So, if fill is also used, the filling and the shading are combined. Therefore, when \fill is used, the default colour (black) fills the shape and the ball color is used for the shading. Depending on the blend mode, the black may dominate the shading completely or partially.

Because the nodes are not filled but only shaded, there is no problem in this case.

So, the expected result can be obtained for the paths by redefining \showblend in one of the following two ways:

\newcommand*\showblend[2][]{% o manual, 314 (gweler hefyd gwestiwn Marcos: http://tex.stackexchange.com/q/248721/)
  \begin{scope}[#1,local bounding box/.expanded=#2]
    \begin{scope}[blend group=#2]
      \path [ball color=red] (90:.6) circle (1);
      \path [ball color=green] (210:.6) circle (1);
      \path [ball color=blue] (330:.6) circle (1);
    \end{scope}%
  \end{scope}%
  \node [below=5mm of #2, anchor=mid] {#2};
}

or

\newcommand*\showblend[2][]{% o manual, 314 (gweler hefyd gwestiwn Marcos: http://tex.stackexchange.com/q/248721/)
  \begin{scope}[#1,local bounding box/.expanded=#2]
    \begin{scope}[blend group=#2]
      \shade [ball color=red] (90:.6) circle (1);
      \shade [ball color=green] (210:.6) circle (1);
      \shade [ball color=blue] (330:.6) circle (1);
    \end{scope}%
  \end{scope}%
  \node [below=5mm of #2, anchor=mid] {#2};
}

Either definition produces identical results.

Shaded paths:

shaded paths

Shaded nodes:

shaded nodes

Complete code:

\documentclass[border=10pt,multi,tikz]{standalone}
\newcommand*\showblend[2][]{% o manual, 314 (gweler hefyd gwestiwn Marcos: http://tex.stackexchange.com/q/248721/)
  \begin{scope}[#1,local bounding box/.expanded=#2]
    \begin{scope}[blend group=#2]
      \shade [ball color=red] (90:.6) circle (1);
      \shade [ball color=green] (210:.6) circle (1);
      \shade [ball color=blue] (330:.6) circle (1);
    \end{scope}%
  \end{scope}%
  \node [below=5mm of #2, anchor=mid] {#2};
}
\newcommand*\shownodeblend[2][]{%
  \begin{scope}[#1,local bounding box/.expanded=#2]
    \begin{scope}[blend group=#2]
      \node [ball color=red, circle, minimum size=20mm] at (90:.6) {};
      \node [ball color=green, circle, minimum size=20mm] at (210:.6) {};
      \node [ball color=blue, circle, minimum size=20mm] at (330:.6) {};
    \end{scope}%
  \end{scope}%
  \node [below=5mm of #2, anchor=mid] {#2};
}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \showblend{normal}
  \showblend[xshift=35mm]{multiply}
  \showblend[xshift=70mm]{screen}
  \showblend[xshift=105mm]{overlay}
  \showblend[xshift=0mm,yshift=-40mm]{darken}
  \showblend[xshift=35mm,yshift=-40mm]{lighten}
  \showblend[xshift=70mm,yshift=-40mm]{color dodge}
  \showblend[xshift=105mm,yshift=-40mm]{color burn}
  \showblend[xshift=0pt,yshift=-80mm]{hard light}
  \showblend[xshift=35mm,yshift=-80mm]{soft light}
  \showblend[xshift=70mm,yshift=-80mm]{difference}
  \showblend[xshift=105mm,yshift=-80mm]{exclusion}
  \showblend[xshift=0pt,yshift=-120mm]{hue}
  \showblend[xshift=35mm,yshift=-120mm]{saturation}
  \showblend[xshift=70mm,yshift=-120mm]{color}
  \showblend[xshift=105mm,yshift=-120mm]{luminosity}
\end{tikzpicture}
\begin{tikzpicture}
  \shownodeblend{normal}
  \shownodeblend[xshift=35mm]{multiply}
  \shownodeblend[xshift=70mm]{screen}
  \shownodeblend[xshift=105mm]{overlay}
  \shownodeblend[xshift=0mm,yshift=-40mm]{darken}
  \shownodeblend[xshift=35mm,yshift=-40mm]{lighten}
  \shownodeblend[xshift=70mm,yshift=-40mm]{color dodge}
  \shownodeblend[xshift=105mm,yshift=-40mm]{color burn}
  \shownodeblend[xshift=0pt,yshift=-80mm]{hard light}
  \shownodeblend[xshift=35mm,yshift=-80mm]{soft light}
  \shownodeblend[xshift=70mm,yshift=-80mm]{difference}
  \shownodeblend[xshift=105mm,yshift=-80mm]{exclusion}
  \shownodeblend[xshift=0pt,yshift=-120mm]{hue}
  \shownodeblend[xshift=35mm,yshift=-120mm]{saturation}
  \shownodeblend[xshift=70mm,yshift=-120mm]{color}
  \shownodeblend[xshift=105mm,yshift=-120mm]{luminosity}
\end{tikzpicture}
\end{document}
cfr
  • 198,882
  • Thank you! I feel incredibly dumb now :(. I hope you do not mind my edit. (Feel free to roll back if you do.) I thought it might be helpful to explain why using \fill goes wrong in the way it does and to include a complete example of the blend modes by way of reference. – cfr Aug 24 '16 at 12:19
  • @cfr No problem, I appreciate it. Just a shame I can't upvote it:) – Christoph Frings Aug 24 '16 at 17:32