繁体   English   中英

渲染具有透明度的纹理时,OpenGL不需要的像素

[英]OpenGL unwanted pixels when rendering a texture with transparency

我一直在努力解决这个问题。 当我使用OpenGL渲染2D纹理时,在无透明度和一些透明度之间的过渡上具有透明度值,我得到一些恼人的灰色像素,我认为这是像素值插值的产物。 关于如何改进的任何想法?

我附上一张图片来举例说明我在说什么: 红色箭头显示一些不需要的像素可见的部分

不是我认为它会有所作为,但我正在使用Qt创建一个QGLWidget和C ++。

解决了:

我一直试图解决这个问题。 我尝试使用带有预乘Alpha通道的图像,使用单独的颜色和alpha混合函数...对我来说没有任何效果,我可能做错了,我不知道。 对我来说,使用抗锯齿输出.png图像是有效的:在Adobe Illustrator上键入优化(提示)并使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

希望这有助于其他人有同样的问题:)

再次感谢你的帮助。

简短的回答:Nicol Bolas是对的,你应该研究预乘的alpha,这是解释原因的数学。

为什么它不能正常工作

以下是非预乘alpha的工作原理。

当复合物的源纹理颜色和alpha(C S,αS)到目的地(C d,αd),则得到下式:

C =αS(C S)+(1 - αS)C d

现在,如果我们有层两个纹理,第一(C 1,α1),然后(C 2,α2),我们得到下式:

C =α2 C 2 +(1 - α2)(α1 C 1 +(1 - α1)C d)

如果我们想要使用预合成纹理一步完成此操作,就像渲染到纹理的方式一样,我们需要重新排列此公式以匹配原始公式:

C =(α2 C 2 +(1 - α2)α1 C 1)+(1 - α2)(1 - α1)C d

αS(C S)=α2 C 2 +(1 - α2)α1 C 1

(1 - αS)C d =(1 - α2)(1 - α1)C d

我们可以解决αS

αS = 1 - (1 - α1)(1 - α2)=α1 +α2 - α1α2

但是当我们解决C S时

(C S)=(α2 C 2 +(1 - α2)α1 C 1)/(α1 +α2 - α1α2)

没有OpenGL混合模式可以让我们正确计算C S.

如果alpha预乘的怎么办?

预乘Alpha混合的公式是不同的:

C = C S +(1- αS )C D.

有两个纹理,

C = C 2 +(1 - α2)(C 1 +(1 - α1)C d)

当我们重新排列以匹配第一个公式时,我们得到:

C = C 2 +(1 - α2)C 1 +(1 - α2)(1 - α1)C d

然后我们解决:

αS = 1 - (1 - α1)(1 - α2)=α1 +α2 - α1α2

(C S)= C 2 +(1 - α2)C 1

这与以下内容相同:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

所以,如果你对所有纹理使用预乘的alpha,那么所有数学运算都很完美,你不必担心这些东西。 只需在任何地方使用相同的混合功能,在任何地方使用预乘的alpha,你可以按照自己喜欢的任何顺序组合。

预乘的alpha也会正确插值,而非预乘的alpha则不然,但这是一个单独的问题。

摘要

预乘的合成运算符是关联的 ,这意味着你可以采用一堆图层并将它们压缩成一个纹理,完全按照你想要的方式。

如果没有预先乘以的alpha,数学就不会按照你想要的方式运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM