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

Thread: Blending RBG with a seperate Alpha map

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2003
    Location
    Johannesburg, South Africa
    Posts
    28

    Blending RBG with a seperate Alpha map

    I've looked through all the old topics on masking and blending but none of them help me much.

    I have a dynamic alpha map that needs to be combined with an RGB texture.
    I'm using multipass rendering and cannot use RGBA or multitexturing due to the dynamic alpha maps and many texture layers that I will add later.

    So far I have placed my alpha map onto the primitive (pass 1) and then I blend my texture onto the primitive using the previous passes alpha map as the transparency (pass 2).
    However it doesn't work and I can't figure out why.

    Here is my code.

    // Sand texture loaded in RGB format
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, Image);

    // Alpha map loaded in ALPHA format
    glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512, 512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, Image);

    glColor3f(1,1,1);
    glDisable(GL_DEPTH_TEST);

    glBindTexture(GL_TEXTURE_2D, AlphaMap);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_TRIANGLE_STRIP);
    glTexCoord2f(0,0);
    glVertex3f(0,400,0);
    glTexCoord2f(0,1);
    glVertex3f(0,0,0);
    glTexCoord2f(1,0);
    glVertex3f(400,400,0);
    glTexCoord2f(1,1);
    glVertex3f(400,0,0);
    glEnd();
    glDisable(GL_TEXTURE_2D);

    // sand
    glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA);
    glEnable(GL_BLEND);
    glBindTexture(GL_TEXTURE_2D, SandTexture);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_TRIANGLE_STRIP);
    glTexCoord2f(0,0);
    glVertex3f(0,400,0);
    glTexCoord2f(0,1);
    glVertex3f(0,0,0);
    glTexCoord2f(1,0);
    glVertex3f(400,400,0);
    glTexCoord2f(1,1);
    glVertex3f(400,0,0);
    glEnd();

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);


    My blending equation should be :
    (Dr; Dg; Db; Da) = (Sr*Da; Sg*Da, Sb*Da; Sa*Da)

    Why doesn't glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA) seem to work?

    Paul

    [This message has been edited by surgptr (edited 05-05-2003).]

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Feb 2000
    Location
    Sweden
    Posts
    2,978

    Re: Blending RBG with a seperate Alpha map

    The blending equation is
    Code :
    Dc = Sc * Sf + Dc * Df
    where Sc and Dc is the source and destination color, and Sf and Df are the source and destination factors (first and second parameter of glBlendFunc).

    You want Sc * Dc.a, so just identify this with the equation above and we get this.
    Code :
    Sf = Dc.a = GL_DST_ALPHA
    Df = 0    = GL_ZERO
    Which is set like this.
    Code :
    glBlendFunc(GL_DST_ALPHA, GL_ZERO);

  3. #3
    Senior Member OpenGL Guru
    Join Date
    Feb 2000
    Location
    Sweden
    Posts
    2,978

    Re: Blending RBG with a seperate Alpha map

    Sorry, I was a little bit too quick to answer your question and didn't really read through it enough and I want to add some details.

    This method will not produce any transparency. It will only scale the output color using the destination alpha as scale factor. For example, if alpha is zero, black will be written to the frame buffer, no matter what was there before. If you want transparency, you need to interpolate the source and destination color using, in this case, the destination alpha as interpolation factor. This should act more like transparency.
    Code :
    glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
    Also note that this method requires a destination alpha channel.

    Second, you should think about going for multitexturing instead. You can easily combine the alpha map and the base texture to a single pass.

  4. #4
    Junior Member Newbie
    Join Date
    Apr 2003
    Location
    Johannesburg, South Africa
    Posts
    28

    Re: Blending RBG with a seperate Alpha map

    Originally posted by Bob:
    If you want transparency, you need to interpolate the source and destination color using, in this case, the destination alpha as interpolation factor. This should act more like transparency.
    Code :
    glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
    Also note that this method requires a destination alpha channel.

    Second, you should think about going for multitexturing instead. You can easily combine the alpha map and the base texture to a single pass.
    Ok I tried glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA) but all that happens is that I get a sand texture.
    I did check that my video card supports destination alpha (which it does) since not all accelerators or OpenGL implementations support DST_ALPHA.

    About the multitexturing - I would love to use multitexturing but how would I combine 6 sets of alpha and color maps and then combine all of the results together? At the moment the only solution I can see is by building up an image through accumulation.

    BTW - Can you recommend any good books that focus specifically on blending/masking?
    All the books I have only devote 5-10 pages on blending and they approach it from a high level. Something that explains it at the pixel level with flow diagrams of the process would help immensely.

    Paul

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Feb 2000
    Location
    Sweden
    Posts
    2,978

    Re: Blending RBG with a seperate Alpha map

    You said your card supports destination alpha, but do you have a pixel format that have a destination alpha channel? If you don't explicitly ask for destination alpha when you set pixel format, you probably won't get it, so make sure you're really asking for a destination alpha channel.

    For information on blending, the equation I gave above is really all you need to know about blending. The incomming color is multiplied by a factor, and the destination color is also multiplied by a factor, and then they are added together (see note 1 below) and finally stored in the frame buffer. Anything else is just techniques to use the blending equations to achieve different effects, but as long as you know what you want and can express it as an equation, you don't need anything else, it's just identification with the base equations. Maybe the OpenGL specification (look around this site in the documentation section) have something of interest.

    note 1: Addition is only one blend function, you can subtract and use min/max functions too. See the spec for more info.

  6. #6
    Junior Member Newbie
    Join Date
    Apr 2003
    Location
    Johannesburg, South Africa
    Posts
    28

    Re: Blending RBG with a seperate Alpha map

    [QUOTE]Originally posted by Bob:
    You said your card supports destination alpha, but do you have a pixel format that have a destination alpha channel? If you don't explicitly ask for destination alpha when you set pixel format, you probably won't get it, so make sure you're really asking for a destination alpha channel.

    Thanks Bob!
    You hit the problem right on the head.

    I had to tell SDL to set up a destination alpha channel with 8 bit resolution.
    i.e. SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, ;

    The blending works perfectly now.
    Paul

  7. #7
    Junior Member Newbie
    Join Date
    Apr 2003
    Location
    Johannesburg, South Africa
    Posts
    28

    Re: Blending RBG with a seperate Alpha map

    The DST_ALPHA works great except when you want to apply another alpha map.

    How can I get glBlendFunc to blend my textures like this :
    SRC * (0,0,0,1) + DST (1,1,1,0)

    i.e. I want to replace the alpha channel in DST with a new alpha channel from SRC image.

    There doesn't seem to be any way of only manipulating alpha channels in OpenGL.

    Texture mapping the alpha map over the existing color map without blending doesn't work either.
    It just replaces the color map.

    Or is there some way that I can switch off color mapping while I replace the alpha channel and then switch it back on when I'm done?

    What I'm trying to achieve is this :
    - Texture map primitive with base texture
    - Apply alpha map 1
    - Blend in grass texture with alpha map 1
    - Apply alpha map 2
    - Blend in sand texture with alpha map 2
    - Apply alpha map 3
    - Blend in rock texture with alpha map 3
    - Apply alpha map 4
    - Blend in snow texture with alpha map 4
    ...

  8. #8
    Senior Member OpenGL Guru
    Join Date
    Feb 2000
    Location
    Sweden
    Posts
    2,978

    Re: Blending RBG with a seperate Alpha map

    SRC * (0,0,0,1) + DST (1,1,1,0) can be achieved in two ways.

    #1: By using separate blending equations for RGB and A. With glBlendFuncSeparate you can control the RGB and A blending separately. glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO) should be the blending function you want. First two is for RGB, and last two for A.

    #2: By masking the RGB portion out by disable color writes. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE) will disable writes for RGB and enable writes for A. That is what the function above does, RGB from destination and A from source.

    That was an answer to your blending problem, now to an answer to what you're trying to achieve. As I understand it, you're going to do an 8-pass rendering, where alpha 1 controls how much of grass you want, and alpha 2 controls how much sand you want, and so on. So basically you want A1*grass + A2*sand + ... (you're not clear whether you actually want to add the different stages, just tell me if you want something else, but for now I assume you want addition).

    This is a perfect situation for multitexturing, where you can combine alpha 1 and gras in one pass, alpha 2 and sand in a second pass, and so on, giving only 4 passes.

    For each base texture (that is, grass, sand, rock and snow), bind the base texture on texture unit 0, and the corresponding alpha map on texture unit 1, and setup the texture environment like this.
    Code :
    glActiveTexture(GL_TEXTURE0);
    glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnv(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
    glTexEnv(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
    glActiveTexture(GL_TEXTURE1);
    glTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnv(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
    glTexEnv(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
    glTexEnv(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_ALPHA);
    glTexEnv(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
    And use additive blending to blend different passes. That is, glBlendFunc(GL_ONE, GL_ONE).

  9. #9
    Junior Member Newbie
    Join Date
    Apr 2003
    Location
    Johannesburg, South Africa
    Posts
    28

    Re: Blending RBG with a seperate Alpha map

    The glBlendFuncSeparate solution works but the framerate dropped from 150 fps to less than 1 fps. Probably due to my old TNT2 not supporting the operation.

    The disable color writes solution works very well and doesn't seem to affect the framerate at all.

    The multitexturing solution just gives me a black screen. I think there's something wrong with the texture environment setup but I'll go and wade through the OpenGL 1.4 spec and see if I can figure it out.

    Your assumption was right about adding each stage together (A1*T1 + A2*T2 + ... ) so multitexturing will work nicely for my application but I didn't know that you could blend alpha and color maps together using multitexturing.
    It should also give me much better performance since I will only have to push half as many vertices down the pipeline.

    Paul

  10. #10
    Senior Member OpenGL Guru
    Join Date
    Feb 2000
    Location
    Sweden
    Posts
    2,978

    Re: Blending RBG with a seperate Alpha map

    I now see an error in the environment setup. In the second texture unit GL_OPERAND1_RGB should be GL_SRC_ALPHA, not GL_ALPHA.

    And less than 1 fps for glBlendFuncSeparate on a TNT2 is pretty much as expected. Separate blending functions is a part of the imaging subset, and the TNT2 doesn't support much of it in hardware.

    [This message has been edited by Bob (edited 05-06-2003).]

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 0
    Last Post: 08-10-2014, 09:14 AM
  2. Replies: 3
    Last Post: 06-16-2011, 12:51 PM
  3. alpha blending without modifying destination alpha
    By GordAllott in forum OpenGL: Advanced Coding
    Replies: 3
    Last Post: 09-21-2009, 04:15 AM
  4. Source Alpha Blending without an Alpha Buffer
    By niallm in forum OpenGL ES
    Replies: 1
    Last Post: 06-18-2009, 02:51 AM
  5. seperate glTexCoords for alpha channel?
    By in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 02-25-2004, 01:39 PM

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