Depth, blending & cullingGL 1.4

glBlendFuncSeparate

glBlendFunc with one pair of factors for the colour channels and another for alpha.

Signature

void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);

How it works

glBlendFunc uses the same two factors for red, green, blue and alpha. That is fine on screen, where nobody looks at the stored alpha, but it goes wrong when you blend into a texture you will use later: with GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA the stored alpha becomes a² + d(1 − a), which is too small, and the texture comes out more transparent than it should.

With separate factors the colour blends as usual and the alpha accumulates coverage correctly:

RGB = src × srcRGB + dst × dstRGB A = srcA × srcAlpha + dstA × dstAlpha

sourceshader output× 0.3SRC_ALPHA+destinationalready drawn× 0.7ONE_MINUS_SRC_ALPHA=result(101, 81, 158)
Classic transparency, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA): a fragment with alpha 0.3 keeps 30% of its own colour and 70% of what was already drawn. Channel by channel: 220 × 0.3 + 50 × 0.7 = 101 for red.

Parameters

srcRGBGLenum

Factor for the new colour.

dstRGBGLenum

Factor for the stored colour.

srcAlphaGLenum

Factor for the new alpha. Usually GL_ONE.

dstAlphaGLenum

Factor for the stored alpha. Usually GL_ONE_MINUS_SRC_ALPHA.

Tips & pitfalls

  • Premultiplied alpha (colour already multiplied by alpha in the shader or texture) uses GL_ONE, GL_ONE_MINUS_SRC_ALPHA for both pairs, so plain glBlendFunc is enough there.

Errors

When the call is invalid it does nothing and sets an error, which glGetError returns:

GL_INVALID_ENUM
A factor is not an accepted value.

Example

example.cpp
1// transparent UI drawn into an offscreen texture
2glEnable(GL_BLEND);
3glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,  // colour
4                    GL_ONE,       GL_ONE_MINUS_SRC_ALPHA); // alpha
Official Khronos documentation