Many texture loading frameworks implicitly convert images into premultiplied-alpha format. This is because many of them are doing image re-drawing into a new image, and CGBitmapContext doesn't support straight-alpha (non-multiplied) image. Consequently, they will usually generate premultiplied-alpha image Graphics and GPU Programming Programming OpenGL. Started by Mogwaii April 15, 2012 07:41 PM. 4 comments, last by Mogwaii 8 years, 6 months ago Advertisement. Mogwaii Author. 105 April 15, 2012 07:41 PM. I feel like this should be a simple answer, but for the life of me I cannot find it. I've been rendering my game using the alpha blend mode: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA. To convert a straight alpha color value to premultiplied format, multiply its R, G, and B values by A. To convert premultiplied to straight, divide R, G, and B by A. Note that color information is often represented as byte values ranging from 0 to 255 (for example the Windows.UI.Color structure consists of 4 bytes)
The source alpha's parameter is GL_ONE rather than GL_SRC_ALPHA because it is being multiplied by the source alpha already. It is often useful to perform premultiplied alpha blending, a slight modification of standard linear interpolation. Premultiplication is so named because the RGB source color has already been multiplied by the alpha Another suggested thing is premultiplying the color with the destination alpha, since OpenGL can only have 1 factor, but it needs 2 factors for correct SourceOver. However, I cannot make sense of that at all. If I'm premultiplying (1, 0, 0) with the destination alpha value of, say, (0.1), I get (0.1, 0, 0) (as suggested here for example). Now I can tell OpenGL the factor GL_ONE_MINUS_SRC_ALPHA. Premultiplied alpha just means that all input color values are already multiplied with the alpha value. Normal alpha blending then requires different blend function. Instead of SRC_ALPHA,1-SRC_ALPHA you need to use 1,1-SRC_ALPHA as you have already tried. What you were missing was taking premultiplied alpha into account in the shader With premultiplied alpha, the RGB components represent the emission of the object or pixel, and the alpha represents the occlusion. A more obvious advantage of this is that, in certain situations, it can save a subsequent multiplication (e.g. if the image is used many times during later compositing) . For example, if you are rendering some leaves, you have an alpha channel indicating the leaf edges. Rendering with the standard blend mode (alpha, 1-alpha) results in color bleeding in around the leaf edges. (ie. black
Enter Pre-multiplied alpha With pre-multiplied alpha, we multiply the texture components by the alpha component first, before storage. We also modify the blend function, changing SourceColor.a to One: DestinationColor.rgb = (SourceColor.rgb * One) + (DestinationColor.rgb * (1 - SourceColor.a)) In OpenGL, I am using GL_SRGB8_ALPHA8 for the OpenGL internal texture format for my textures and render targets. This eliminated some banding I was seeing in dark opaque areas. However, in the following screenshot, you can see there is still some banding in the nearly-opaque black pixels on the left side. The render target is transparent in the areas where you see the checkerboard pattern Premultiplied alpha itself does not give you order independent transparency, no. What are some methods to render transparency in OpenGL. 4. How to store > 256 transparency values in textures? 7. Additive blending with weighted-blended order independent transparency. 3. Volumetric raycasting with transparent rasterized geometry . 2. How does the Painter's Algorithm handle transparency? 5. Premultiplied Alpha. Recall how we talked about opacity - if the object is partially opaque the contribution of its color to the output is also partial. Premultiplied alpha makes this idea explicit. The values of the RGB components are, as the name implies, premultiplied by the alpha component. Starting with a non-premultiplied color: (1.00, 0.80, 0.30, 0.40) Alpha premultiplication results.
Premultiplied alpha is simpler to understand when you think about it in terms of masking rather than math. For small jobs, you may not need to know what kind of images you're using. But as soon as you do something relatively complex with more than two layers, knowing what premultiplied means and when to use it will pay dividends. As a rule of thumb, you can usually pre-mask or pre-multiply. . Premultiplied alpha offers several advantages over conventional, non-premultiplied alpha, because it better represents the real-world interaction of light with physical materials by separating the texel's color contribution (the color that it adds to the scene) from its translucency (the amount of underlying color that it allows through) Since the Alpha has been refactored, the Alpha channel is always recorded in a kind of Premultiplied mode when we use the OpenGL render, even if you save your image in PNG. Not in Straight mode. I say a kind of because if I interpret the rendered image in After Effects as a premultiplied footage, anti-aliased pixels are wrong too.
That's why I added a section explaining about the blending of the alpha for the non-premultiplied case. Alfonse 11:48, 26 GL_ONE_MINUS_SRC_ALPHA). You're right that very often with OpenGL, people discard the destination alpha, but some people just don't realize that a correct over operator with straight alpha blending is to use glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL. setBlendMode(one, one_minus_src_alpha) -- set up premultiplied alpha blending. getBlendMode() returns one, one_minus_src_alpha Internally, there is a new blend mode advanced and the src and dst factors are tracked as separate state. This implementation could be cleaned up a little by making the friendly modes work on top of the real. With OpenGL, only the people that learned how to do advanced multi-pass rendering were forced to grok premultiplied alpha. Now WebGL inside HTML has made it really easy to combine multiple sources, and that's one reason why it's more important to know about premultiplied blending than it used to be
Alpha compositing, OpenGL blending and premultiplied alpha: 01-Feb-2019: Constructing a cubic Bezier that passes through four points: 14-Feb-2018 : Efficient Rendering of Linear Brush Strokes—my graphics paper explained: 25-Sep-2017: Creating a modern OpenGL context: 04-Mar-2017: Exploring bump mapping with WebGL: 30-Nov-2016: Hitchikers Guide To The GDB: 04-Sep-2016: Exploring calling. Re: [Freeframe-develop] FreeFrameGL + Premultiplied Alpha. From: Edwin de Koning <edwin@re...> - 2015-03-02 19:55:3 I would say that if an alpha channel is present then its unpremultiplied, if its not then obviously its premultiplied. I usually also treat the alpha channel specially and don't blend it the same way as the rgb channels. I think of them as a hint about how to blend instead of a color to blend. But then again I use shaders to blend instead of the old OpenGL blending modes which were always so. Premultiplied Alpha Blending . There is an important variant of alpha blending: sometimes the fragment color has its alpha component already premultiplied to the color components. (You might think of it as a price that has VAT already included.) In this case, alpha should not be multiplied again (VAT should not be added again) and the correct blending is: Blend One OneMinusSrcAlpha. which.