OpenGL

Blending with OpenGL: glBlendFunc and friends

Note: WORK IN PROGRESS!!

Enabling blending

This is the first thing to do:


glEnable(GL_BLEND);

otherwise we won't be able to notice any difference at all!

glBlendFunc


void glBlendFunc(GLenum sfactor, GLenum dfactor)

Specifies how the incoming values (what you're going to draw) are going to affect the existing values (what is already drawn).

In other words:

  • Incoming values == Source
  • Existing values == Destination

So what we are setting with glBlendFunc is the multiplying factors for both source and destination. The source factor will multiply the incoming values, and the destination factor will multiply the existing values, and then both will be added together to form the final result. This is a vectorial sum: the red, green, blue and alpha components of each pixel are taken into account separately.

Mathematically (and succintly) expressed:


Result = SourceFactor * SourceValues + DestinationFactor * DestinationValues

And since we're talking vectorially here:


Result = (SFr * SVr, SFg * SVg, SFb * SVb, SFa * SVa) + (DFr * DVr, DFg * DVg, DFb * DVb, DFa * DVa)

which results in


Result(R, G, B, A) = (SFr * SVr + DFr * DVr, SFg * SVg + DFg * DVg, SFb * SVb + DFb * DVb, SFa * SVa + DFa * DVa)

Blending factors

There are many blending factors, although we usually only end up using a handful of them. Most of them use the alpha value of the incoming pixels to decide whether they are shown or not, or how much of them is shown (tipically in order to achieve translucency).

The equivalent to having blending disabled is to use (GL_ONE, GL_ZERO) --or in other words, multiply the source by 1 (i.e. don't change its value) and multiply the destination by zero (i.e. ignore its value), then add it together. Which effectively replaces everything already in the framebuffer with the incoming, new values.

Sources