Textures with alpha and linear mapping

I am using some textures that have an alpha channel. In some cases, there is a coloured pixel next to a transparent pixel, and the transparent pixel has a different colour. Let’s say a normal green pixel right next to a transparent pixel that happens to have red in it’s colour values. When using linear mapping, the texture pixels are smoothed together, and the result is a red edge on the green pixel. OpenGL seems to blend the colours and the alpha independently.

The same issue happens when generating mipmaps. A textured object may look OK closeup with the full-resolution texture, but due to the pixel mixing at the transparent edge, the mipmaps end up red-tinged on the edges, and this becomes visible when the objects are rendered small.

My textures are software rendered, and I have added some cases where I can bleed the texture colours further out into the transparent areas, but there are cases where this is not practical.

Ideally, a linear mapping between the green pixel and the transparent pixel should be half-transparent green, instead of half-transparent half-green-half-red.

Is there a way to tell OpenGL to linear-map the texture pixels taking the alpha channel into account?

Use pre-multiplied alpha.

Conversion from un-multiplied alpha to pre-multiplied alpha converts (r,g,b,a) to (ra,ga,b*a,a). This needs to be done to the image data before it’s uploaded to the texture. Some image-loading libraries have an option to do this automatically.

Blending with pre-multiplied alpha uses glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) rather than glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).

Essentially, what you need to do is use premultiplied alpha:
https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre

But there’s no simple switch to tell OpenGL to multiply color values with alpha before filtering when sampling a texture. You will have to do that yourself and store premultiplied values in the texture.

[QUOTE=surfdabbler;1272269]…When using linear mapping, the texture pixels are smoothed together, and the result is a red edge on the green pixel. OpenGL seems to blend the colours and the alpha independently.

The same issue happens when generating mipmaps. …the mipmaps end up red-tinged on the edges, and this becomes visible when the objects are rendered small.[/QUOTE]

You’ve already got the answer. Here’s more good reading on Pre-multiplied Alpha:

Thanks! Looks like just what I wanted. :slight_smile: Thanks for the blending tip too - the references are not very blatant about this, so it would have been easy to spend a lot of time trying to work this one out.