问题描述
我已经为这个问题苦苦挣扎了一段时间.当我使用OpenGL渲染2D纹理时,该2D纹理在无透明度和某些透明度之间的过渡上具有透明度值,我会得到一些令人讨厌的灰色像素,我认为这是像素值插值的产物.关于我该如何改善的任何想法?
I've been struggling with this problem for a while now. When I use OpenGL to render 2D textures, which have transparency values on the transition between no transparency and some transparency, I get some annoying grey pixel which I assume are a product of pixel value interpolation. Any ideas on how I can improve that?
我要附上一张图片,以说明我在说什么:
I'm attaching an image to exemplify what I'm talking about:
不是我认为这会有所作为,但我正在使用Qt创建QGLWidget和C ++.
Not that I think it will make a difference but I'm using Qt to create a QGLWidget and C++.
已解决:
一段时间以来,我一直在尝试解决此问题.我尝试使用具有预乘Alpha通道的图像,并使用单独的混合功能来处理颜色和Alpha ...对于我来说,什么都没做,我可能做错了,我不知道.对我来说,有效的方法是在Adobe Illustrator上导出具有抗锯齿功能的 .png 图像:类型优化(提示),并使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
I've been trying to solve this problem for a while. I tried using images with pre-multiplied alpha channel, using separate blend functions for color and alpha... For me nothing worked, I've might have done it wrong, I don't know. For me what worked was exporting the .png image with Anti-Aliasing: Type Optimized (Hinted) on Adobe Illustrator and using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
希望这可以帮助遇到相同问题的其他人:)
Hope this helps other people with the same problem :)
再次感谢您的遮阳篷.
推荐答案
简短答案:Nicol Bolas是对的,您应该研究预乘alpha,这是解释原因的数学.
Short answer: Nicol Bolas is right that you should investigate pre-multiplied alpha, and here's the math that explains why.
这是非预乘alpha的工作方式.
Here's how things work with non-premultiplied alpha.
将具有颜色和alpha(C ,α)的源纹理合成到目标(C ,α),您将获得公式:
When you composite a source texture with color and alpha (C, α) onto a destination (C, α), you get the formula:
现在,如果我们有两个纹理层,首先是(C ,α),然后是(C ,α),我们得到公式:
Now, if we have layer two textures, first (C, α) and then (C, α), we get the formula:
如果我们要使用预合成的纹理一步一步地完成此操作,例如您要渲染到纹理的方式,则需要重新排列此公式以匹配原始公式:
If we want to do this in one step with a pre-composited texture, like the way you are rendering to a texture, we need to rearrange this formula to match the original formula:
α C =α C +(1-α)α C
α C = α C + (1 - α) α C
(1-α)C =(1-α)(1-α
(1 - α) C = (1 - α) (1 - α) C
我们可以求解α:
但是当我们求解C 时:
But when we then solve for C:
没有可以使我们正确计算C 的OpenGL混合模式.
There's no OpenGL blending mode that lets us calculate C correctly.
预乘alpha混合的公式不同:
The formula for pre-multiplied alpha blending is different:
具有两个纹理,
当我们重新排列以匹配第一个公式时,我们得到:
When we rearrange to match the first formula, we get:
然后我们解决:
C = C +(1-α)C
C = C + (1 - α) C
这与以下内容相同:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
因此,如果您对所有纹理使用预乘Alpha,则所有数学运算都将完美完成,而您不必担心这些问题.只需在各处使用相同的混合函数,在各处使用预乘的alpha,就可以按自己喜欢的顺序合成事物.
So, if you use pre-multiplied alpha for all of your textures, then all the math works out perfectly, and you don't have to worry about this stuff. Just use that same blend function everywhere, use pre-multiplied alpha everywhere, and you can composite things in any order you like.
预乘alpha也可以正确插值,这对于非预乘alpha并不正确,但这是一个单独的问题.
Pre-multiplied alpha also interpolates correctly, which is not true of non-premultiplied alpha, but this is a separate issue.
预乘组合运算符是 associative ,这意味着您可以按照自己想要的方式将一堆图层压缩为一个纹理.
The pre-multiplied composition operator is associative which means that you can take a bunch of layers and squash them into one texture, exactly the way you want.
没有预乘Alpha运算,数学就无法达到您想要的方式.
Without pre-multiplied alpha, the math doesn't work out the way you want.
这篇关于使用透明效果渲染纹理时OpenGL不需要的像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!