Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Transparency math, unexpected result!

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    23

    Transparency math, unexpected result!

    Hi all, I just found something interesting... so I'm trying to combine two colors and their alpha values to give me another value, with a standard "over" operation, like the in http://en.wikipedia.org/wiki/Alpha_compositing.

    To make it happen, I use code like this:
    Code :
    result.rgb = over.rgb * over.a + under.rgb * under.a * (1.0 - over.a);
    result.a = 1.0 - (1.0 - over.a) * (1.0 - under.a)

    So, if I put the color (1.0, 1.0, 1.0, 0.5) over (0.0, 0.0, 0.0, 0.0), I would expect to get (1.0, 1.0, 1.0, 0.5) back, but running through the math, I get:


    result.rgb = (1.0, 1.0, 1.0) * 0.5 + (0.0, 0.0, 0.0) * 0.0 * (1.0 - 0.5);
    result.a = 1.0 - (1.0 - 0.5) * (1.0 - 0.0);
    which gives me (0.5, 0.5, 0.5, 0.5).

    If I lay a color over nothing, shouldn't I get the original color back? Shouldn't the result of this operation be (1.0, 1.0, 1.0, 0.5)?

    Could someone please explain this to me? I have a feeling I'm missing something very basic in combining colors...

    Thanks!

  2. #2
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,574

    Re: Transparency math, unexpected result!

    As you multiply incoming color by its alpha, here it is 0.5, so this result is expected.

  3. #3
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,672

    Re: Transparency math, unexpected result!

    Since you didn't seem to read it the first time, I'll just quote what I said in your other thread.

    Quote Originally Posted by me
    The equation you quoted is correct if you are only looking at two objects being blended together. When you have layers upon layers, you have to composite them one at a time. In doing so, each layer's color gets its own alpha multiplied into itself (Ca * alpha_a). So the destination color already had its alpha factored in; there's no need to do it twice.

  4. #4
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    23

    Re: Transparency math, unexpected result!

    I actually did read it the first time, I just have a hard time wrapping my mind around this math... its very unintuitive to me. Odd that I can understand calculus but colors can get the best of me.

    I read somewhere that if I discard the multiplying by the alpha, I have to do it beforehand, if I want correct blending. But they also said that when I do this, I lose the "order" of multiple layers. So I'm kind of nervous about taking anything out of the equation.

    If I change this
    Code :
    result.rgb = over.rgb * over.a + under.rgb * under.a * (1.0 - over.a);
    to this
    Code :
    result.rgb = over.rgb + under.rgb * under.a * (1.0 - over.a);
    and I try (1, 1, 1, .5) with (1, 1, 1, .5), I get (1.25, 1.25, 1.25, .75), when I would expect (1, 1, 1, .75).

    If I change it to
    Code :
    result.rgb = over.rgb * over.a + under.rgb * (1.0 - over.a)
    and try (1, 1, 1, .5) with (0, 0, 0, 0), I get (.5, .5, .5, .5), when I would expect (1, 1, 1, .5).

    Isn't there an equation that can handle all these cases?

  5. #5
    V-man
    Guest

    Re: Transparency math, unexpected result!

    You should use the mix() instead of this

    result.rgb = over.rgb * over.a + under.rgb * under.a * (1.0 - over.a);

  6. #6
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,574

    Re: Transparency math, unexpected result!

    Yeah if fact you are simply confused because of the under.a term, remove it and it will be easier.

  7. #7
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    23

    Re: Transparency math, unexpected result!

    The glsl spec says that mix() is x*(1-a)+y*a; in my terms thats over.rgb*over.a + under.rgb*(1-over.a), so it's mine without the under.a term.

    But wont this fail if I mix (1, 1, 1, .5) and (0, 0, 0, 0)? It would incorrectly give me (.5, .5, .5, .5).

  8. #8
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,672

    Re: Transparency math, unexpected result!

    But wont this fail if I mix (1, 1, 1, .5) and (0, 0, 0, 0)? It would incorrectly give me (.5, .5, .5, .5).
    Two things:

    1: If "under.a" was in the computation, you'd get the same thing. Which is part of the reason why you don't need it.

    2: That is the correct value.

  9. #9
    Junior Member Newbie
    Join Date
    Jan 2011
    Posts
    23

    Re: Transparency math, unexpected result!

    But it isnt the correct value, I get a gray out of this. I wanted a half-transparent white.

    Anyway, I did a bit of number-crunching, and I came up with this formula:

    overpower = over.a
    underpower = under.a * (1 - over.a)
    overcontribution = overpower / (overpower + underpower)
    undercontribution = underpower / (overpower + underpower)
    result.rgb = over.rgb * overcontribution + under.rgb * undercontribution;

    Photoshop seems to agree with me, because it gave me the same results for (1, 1, 1, .5) over (1, 0, 0, .5), which was (1, .67, .67, .75)

  10. #10
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,672

    Re: Transparency math, unexpected result!

    But it isnt the correct value, I get a gray out of this. I wanted a half-transparent white.
    There's no such thing as "half-transparent white". Colors don't come with a transparency value.

    If you have a non-premultiplied RGBA vector of (1, 1, 1, 0.5), the actual color of this is (0.5, 0.5, 0.5). That is, this is what you would see.

    Similarly, while your blend function for "(1, 1, 1, .5) over (1, 0, 0, .5)" gives you "(1, .67, .67, .75)" back, the actual color is (1, 0.5, 0.5). Which is what you get if you do a straight linear interpolation between the source and destination based on the source alpha.

    The reason OpenGL doesn't support what you're trying to do in it's blending stage is because OpenGL is designed primarily for rendering colors. Not for rendering transparency. The way you normally deal with transparency is as follows.

    First, you clear the screen. Then you render everything that is opaque. After that, you render all transparent objects in order from farthest from the camera to nearest.

    Therefore, the destination color in a blending operation, the "under" as you keep calling it, will refer to either the background color (the one you cleared the screen to), an opaque color, or the composite between the background or opaque opaque colors and some number of previously-rendered transparent colors.

    The destination alpha doesn't mean anything. It doesn't get factored into the blend equation. This is why a linear interpolation based on the source ("over") alpha works.

    If the destination color is the background color, then it's effectively the same as if its opaque. There's nothing "behind" the background to see, so there's no value there to have blended with.

    If the destination color is an opaque color, then the original alpha for this rendering was 1.0. So the "under.a" is 1.0, which doesn't affect the equation. Linear interpolation gets you a proper color.

    If the destination was a composite of an opaque/background color and some number of layered colors, it still doesn't matter. Because the composite of all of these layers is still fully opaque, and therefore has an effective alpha of 1.0.

    To put it another way, you don't blend two transparent objects together. You're always blending a transparent object with an opaque object.

Page 1 of 2 12 LastLast

Similar Threads

  1. Texture coordinates produce unexpected result
    By wenhaug in forum OpenGL: Basic Coding
    Replies: 6
    Last Post: 05-01-2018, 04:24 PM
  2. NSOpenGLView visual transparency vs. mouse transparency
    By hidefromkgb in forum OpenGL: macOS
    Replies: 1
    Last Post: 05-12-2015, 01:05 PM
  3. unexpected results with GL_LINES
    By Tcll5850 in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 11-18-2014, 06:05 PM
  4. Unexpected fog behavior
    By kevinfishburne in forum OpenGL: Basic Coding
    Replies: 10
    Last Post: 07-21-2012, 03:48 PM
  5. OpenGL window transparency and texture transparency
    By ramalhais in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 03-15-2002, 09:37 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean