PDA

View Full Version : Textures with alpha and linear mapping



surfdabbler
07-23-2015, 07:49 PM
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?

GClements
07-24-2015, 02:12 AM
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.
Use pre-multiplied alpha.

Conversion from un-multiplied alpha to pre-multiplied alpha converts (r,g,b,a) to (r*a,g*a,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).

Firadeoclus
07-24-2015, 02:32 AM
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.

Dark Photon
07-24-2015, 04:37 AM
...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.

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

* Premultiplied alpha (http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%5D%5D) (Forsyth)
* Premultiplied alpha part 2 (http://home.comcast.net/~tom_forsyth/blog.wiki.html#%5B%5BPremultiplied%20alpha%20part% 202%5D%5D) (Forsyth)

surfdabbler
07-26-2015, 11:05 PM
Thanks! Looks like just what I wanted. :) 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.