1

Following problem: I have two textures and I want to combine these two into a new texture. Thus, one texture is used as background, the other will be overlaid. The overlay texture is getting initialized with glClearColor(1.0, 1.0, 1.0, 0.0). Objects are draw onto the texture, these objects do have alpha values.

Now blending between the two textures leaves a white border around the objects. The border comes from the fact that the background color in the second texture is white, isn't it?

How can I use alpha blending where I do not have to think about the background color of the overlaying texture?

Archmede
  • 1,592
  • 2
  • 20
  • 37
Donny
  • 549
  • 2
  • 10
  • 24
  • Wouldn't you like to post this question here instead? http://gamedev.stackexchange.com/ – Alex Sep 16 '11 at 07:43
  • @AlexanderMP: Why? This is purely a graphics question; it has nothing to do with games or game development _specifically_. – Nicol Bolas Sep 16 '11 at 07:46
  • If I thought that it shouldn't belong here at all, I'd vote to close it. However, I think that on a specialized site this question would receive a good answer faster. It was more like a suggestion. :) Here on SO, questions that are hard, or regarding very specific stuff, tend to get lost, sometimes never to be found again unless a bounty is set. – Alex Sep 16 '11 at 07:47
  • I'm afraid I don't understand the question. "The border comes from the fact that the background color in the second texture is white, isn't it?" Which "second texture"? Are you talking about the texture in the back or the texture you overlay on top? Because you just said that you set its background to black and zero-alpha. Did you forget to call `glClear` after setting the clear color? – Nicol Bolas Sep 16 '11 at 07:48
  • @AlexanderMP: My point is that you could say the exact same thing about every question with the OpenGL tag on it. Or D3D tag. And the vast majority of them get answers. There isn't anything that singles _this_ question out from the thousands of others under those tags. – Nicol Bolas Sep 16 '11 at 07:50
  • i'm quite confident with the response speed of stackoverflow, but thanks a lot... – Donny Sep 16 '11 at 07:51
  • @nicol: sorry just changed my question i wanted to clear the background to white, and yes i mean the overlayed texture – Donny Sep 16 '11 at 07:52
  • think of the object i want to draw in the overlaying texture with a decreasing alpha value. Where the alphavalue equals 1 i dont have any problems, when the alpha value starts dropping i can see through my object to the white background. When i start overlaying, the white background gets "copied" to the new background texture – Donny Sep 16 '11 at 07:56
  • You can't ignore the background color. If there is a big background picture, draw that first (with 255 alpha) and then overlay the other ones. If not, perhaps a 127, 127, 127 gray color would in a general case least affect your images. However, for your border problem, you might wanna take a look at this: http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml where it talks about GL_CLAMP_TO_EDGE (under GL_TEXTURE_WRAP_S). Setting the right texture parameter, you can avoid OpenGL drawing the border of the texture which is usually undesired. – Shahbaz Sep 19 '11 at 22:57

4 Answers4

6

I solved the problem myself, but thanks a lot to all of you guys!

The problem was following: to combine both textures I used glblend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) which does not work due to the fact that OpenGL uses pre-multiplied alpha values. Blending with glblend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA), works as the source term now will be: 1*src_alpha*src_color!

Archmede
  • 1,592
  • 2
  • 20
  • 37
Donny
  • 549
  • 2
  • 10
  • 24
1

How can i use alpha blending where i do not have to think about the background color of the overlaying texture?

You can't; your blend function incorporates the background color into it, because it may not actually be the "background". You render multiple objects to the texture, so the "background" color may in fact be a previously rendered object.

Your best bet is to minimize the impact. There's no particular need for the background color to be white. Just make it black. This won't make the artifacts go away; it will hopefully just make it less noticeable.

The simple fact is that blending in graphics cards simply isn't designed to be able to do the kinds of compositing you're doing. It works best when what you're blending with is opaque. Even if there are layers of transparency between the opaque surface and what you're rendering, it still works.

But if the background is actually transparent, with no fully opaque color, the math simply stops working. You will get artifacts; the question is how noticeable they will be.

If you have access to more advanced hardware, you could use some shader-based programmatic blending techniques. But these will have a performance impact.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • by that i would have the same effect, but instead of a white border i would get a black, wouldn't I? – Donny Sep 16 '11 at 08:30
0

Although I think you probably get better results with a black background, as Nicol Bolas pointed out. But you should double check your blending functions, because as you point out, it SHOULD not matter...

1.0 * 0.0 + 0.734 * 1.0 = 0.734

What I don't really get is why your base texture is fully transparent? Is that intended? Unless you blend the textures and then use them somewhere else initializing to Alpha = 1.0 is a batter idea.

rioki
  • 5,988
  • 5
  • 32
  • 55
  • not the base is fully transparent, but the overlay, at least when i clear it at the beginning of a rendercall! after drawing to the texture, of corse there will be some color and alpha values different from 0! – Donny Sep 19 '11 at 14:07
0

Make sure you disable depth writing before you draw the transparent texture (so one transparent texture can't "block" another, preventing part of it from being drawn). To do so just call glDepthMask(false). Once you are done drawing transparent objects, call glDepthMask(true) to set depth writing back to normal.

fintelia
  • 1,201
  • 6
  • 17