View Full Version : OPENGL Blending function - replacing colors slowly in a layering manner

05-25-2012, 12:09 AM
What I am trying to do is add a darker red color with alpha (0.1,0,0,0.2) on top of a bright red (1,0,0,1). For the first layer it works fine, the result is (0.9 ,0 ,0, 1); However when the red value gets to 0.5 it cannot drop below that value.

The first layer is demonstrated with the following equation, and works fine:

ColorBuffer color = (1,0,0,1) Bright Red
SourceColor color = (0.1,0,0,0.2) Dark Red

GL_ONE = 1 , GL_ONE_MINUS_SRC_ALPHA = 1 - 0.2 = 0.8

Cf = (ColorSource * One) + (ColorBuffer * One Minus Src Alpha);
Cf = ((0.1,0,0)*1 ) + ((1,0,0) * 0.8);
Cf = 0.1,0,0 + 0.8,0,0;
Cf = 0.9,0,0 // Here is the result
Now further down the line after many layers, it will get to a point where the destination color is darker : 0.5, now the color never gets any darker as demonstrated below it starts with 0.5,0,0 , but results in 0.5,0,0:

Cf = ((0.1,0,0)*1 ) + ((0.5,0,0) * 0.8);
Cf = 0.1,0,0 + 0.4,0,0;
Cf = 0.5,0,0
Here is the result which means the color buffer has not changed and the color I am overlaying no longer has any effect.

How do I get my dark red to layer until it replaces the bright red?

SIMPLE PROCESSING SKETCH DEMONSTRATING THE PROBLEM - you will notice here I am trying GL_SRC_ALPHA and it still has that problem:


here is an image with the issue, note how the green still shines through.


The image below describes the problem on the LEFT on the RIGHT is the desired effect.


05-25-2012, 02:05 AM
An observation: your blend function is treating ColorSource as if it is pre-multiplied (like CoreGraphics; that is, RGB have already been multiplied by A before reaching the blending stage.)

Undoing the premultiplication, R 0.1 / A 0.2 = 0.5. So, using that blend function, you are blending towards medium red, not dark red. It's doing exactly what you asked.

If you want dark red you need to make your colors match your blend function; either use SRC_ALPHA, ONE_MINUS_SRC_ALPHA, or use darker colors (R = 0.02).