Alpha 与多个纹理混合留下彩色边框
以下问题:我有两个纹理,我想将这两个纹理组合成一个新纹理。因此,一个纹理用作背景,另一个将被覆盖。覆盖纹理使用 glClearColor(1.0, 1.0, 1.0, 0.0) 进行初始化。对象被绘制到纹理上,这些对象确实具有 alpha 值。
现在,两种纹理之间的混合会在对象周围留下白色边框。边框来自于第二个纹理中的背景颜色是白色的事实,不是吗?
如何使用 alpha 混合而无需考虑叠加纹理的背景颜色?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我自己解决了这个问题,但非常感谢大家!
问题如下:为了组合两个纹理,我使用了 glblend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ,由于 OpenGL 使用预乘的 alpha 值,它不起作用。与 glblend(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) 混合,现在的源项将是:
1*src_alpha*src_color!
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!
你不能;您的混合函数将背景颜色合并到其中,因为它实际上可能不是“背景”。您将多个对象渲染到纹理,因此“背景”颜色实际上可能是先前渲染的对象。
最好的办法就是尽量减少影响。背景颜色没有特别需要是白色。把它变成黑色就行了这不会使文物消失;希望它只会让它不那么引人注目。
一个简单的事实是,显卡中的混合根本无法实现您正在执行的合成类型。当您混合的内容是不透明的时,效果最佳。即使不透明表面和渲染内容之间存在透明层,它仍然有效。
但如果背景实际上是透明的,没有完全不透明的颜色,那么数学就会停止工作。你将获得神器;问题是它们会有多引人注目。
如果您可以使用更先进的硬件,则可以使用一些基于着色器的编程混合技术。但这些都会对性能产生影响。
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.
尽管我认为使用黑色背景可能会得到更好的结果,正如尼可波拉斯指出的那样。但是你应该仔细检查你的混合函数,因为正如你所指出的,它应该不重要......
我真正不明白的是为什么你的基础纹理是完全透明的?这是故意的吗?除非你混合纹理然后在其他地方使用它们,初始化为 Alpha = 1.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...
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.
确保在绘制透明纹理之前禁用深度写入(这样一个透明纹理就无法“阻挡”另一个透明纹理,从而阻止绘制其中的一部分)。为此,只需调用
glDepthMask(false)
。完成绘制透明对象后,调用glDepthMask(true)
将深度写入设置回正常状态。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, callglDepthMask(true)
to set depth writing back to normal.