Alright, I’ll give it a shot.
Explain Like I’m 5 Version:
When a mommy pixel loves a daddy pixel, they sometimes make a baby pixel.
This might get confusing, let’s try another approach
Explained How I Understand it:
The Blend Function, as you may have guessed, is a function which defines how two colors combine to make the final color.
It helps if you think of this as a per-pixel process. So don’t think of the entire image in the buffer, just consider one pixel.
First off we need to understand which parts of the functions apply to which color.
Source Color: This is the color you want to draw to the surface (the one you’re currently drawing with).
Destination Color: This is the color which already exists on the surface.
So we have the basic idea:
Source Color + Destination Color = Baby-I mean Final Color.
Blend Function
Well, the above is great and all, but simply adding two colors together isn’t always going to produce the results we want. Thus along comes the Blend Function.
Instead of just adding the two colors together, we’re now going to mangle both colors and then add them together to create the final result. So we’re going to define a function
for how we’re going to mangle each pixel, by using the blend function.
BlendFunc(Mangle Source Function, Mangle Destination Function);
And once we plug the colors into the blending process, we get:
Mangle Source Function * Source Color + Mangle Destination Function * Destination Color = Final Color
Essentially, the function is a scaling factor for the specified color (think multiply each element in a color).
Of course this isn’t the exact math under the hood, but we can overlook that right now.
Blend Function Parameters
You’re probably already familiar with this, but just in case: elements of a color are defined in a 0 to 1 range.
The blend function defines how those elements should be scaled.
Let’s take some simple examples, we’ll be using RGB format:
You already drew your scene and now you want to add some lighting by drawing a circle/sphere over a specific area.
Circle/Sphere = Source Color
Scene = Destination Color
We’ll go ahead and keep this simple by making a medium light completely white. So
Source = (0.5, 0.5, 0.5)
Let’s assume all the colors under the light are dark blue. Thus
Destination = (0, 0, 0.3)
Since we’re making a light, we obviously want to make the dark blue color a lighter shade of blue. So how should we do this?
Easy enough, just slap those two bad boys together with an add function and BAM instant lighting.
How do we tell OpenGL to do this? Well, we us the blending parameter called GL_ONE.
glBlendFunc(GL_ONE, GL_ONE);
This means the source and the destination are going to be multiplied by 1.
And here’s essentially what happens:
Source Color: 1 * (0.5, 0.5, 0.5) = (0.5, 0.5, 0.5)
Destination Color: 1 * (0, 0, 0.3) = (0, 0, 0.3)
Final Color: (0.5, 0.5, 0.5) + (0, 0, 0.3) = (0.5, 0.5, 0.8 )
Note: This actually answers your question about which blend function to use for your lighting. Also, you can change the color and strength of the light
by manipulating the Source Color elements. IE: change to (0,1,0) if you want a really strong green light etc…
I recommend you play with it to get the effect you want, but start with lower numbers and work your way up. Once a color goes out of the 0 to 1 range, it’s clamped to either 0 or 1.
In this example, we’ll use RGBA format. And we’ll tackle a common question when trying to do transparencies.
How do you draw a transparent object on top of a scene?
You’re going to need a transparency value (the alpha element of course). Keep in mind the destination color does not need an alpha value, but the source does.
I think the magic of this one is easier understood by just looking at an example.
The function we’ll use is
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
This means we’re going to multiply the Source Color by the value of the Alpha channel on the source value.
Then we’re going to take 1 and subtract the Source Color Alpha channel. The result is then multiplied against the Destination Color.
So let’s say we want to blend a dark red over a blue Scene. But we only want to blend it by half (in other words, 50% transparency).
Source = (0.3, 0, 0, 0.5)
Destination = (0, 0, 0.3)
And essentially what happens:
Source Color: 0.5 * (0.3, 0, 0, 0.5) = (0.15, 0, 0, 0.25)
Destination Color: (1 - 0.5) * (0, 0, 0.3) = (0, 0, 0.15)
Final Color: (0.15, 0, 0, 0.5) + (0, 0, 0.15) = (0.15, 0, 0.15, 0.5)
The end result is a purple-ish looking color.
If the final destination doesn’t contain alpha values, then to the best of my understanding the alpha channel of the final color is taken to a farm out in the country where it lives the
rest of its days - and wasn’t by any means taken out back and shot.
Other Blend Function Parameters
There are a lot of other parameters you can set. To be honest, you’ll likely see the above two example used the most.
The reason you can use things like GL_DST_ALPHA in the Source parameter, is because sometimes you feel life just isn’t hard enough. No no no, that can’t be right.
I haven’t run into a case where I’ve needed a value from the destination channel, so I can’t really provide an example. But I’m sure there are specific cases where it comes in useful.