Subtractive Shader


I would like to achieve the following effect:
If two sprites overlap, the colors in the overlapping area should blend subtractive, as shown in the following image.

Is there a shader that achieves this effect or can you modify the standard shaders accordingly?

Well you can subtract colors by choosing a proper blend mode / blend factor combination. Instead of the usual alpha blending which is

BlendOp Add
Blend SrcAlpha OneMinusSrcAlpha 

You can use:

BlendOp RevSub
Blend One One

Keep in mind that subtraction happens on each channel seperately and the result is of course clamped between 0 and 1. Also keep in mind that the order matters. subtracting 100% red from 100% yellow would result in 100% green. Though the reverse would be black since:

  (1,1,0) yellow
 -(1,0,0) red
  (0,1,0) green

  (1,0,0) red
 -(1,1,0) yellow
  (0,-1,0) --clamped to 0 --> (0,0,0) black

If you ment that you want to perform subtractive color mixing that’s not really possible in a shader as computer graphics work in an RGB color space (additive color space) while real-world paint mixing happens in a subtactive color space. In theory all you have to do is converting all colors from RGB into CMY, do the mixing and convert them back to RGB. However this is not possible with the available blendmodes. The main problem is the destination color in the frame buffer. It can’t be simply read into the shader. If that would be possible it would be simple

To convert an RGB value into CMY all you have to do is to invert all channels:

000 <-> 111 --> black
100 <-> 011 --> red
010 <-> 101 --> green
001 <-> 110 --> blue
011 <-> 100 --> cyan
101 <-> 010 --> magenta
110 <-> 001 --> yellow
111 <-> 000 --> white


Just like you messed with the blend mode in your last question you can mess with it here and add the Op “sub”.