如何使用glBlendFunc(OpenGL ES 1.x)实现类似于Photoshop屏幕混合的效果?

3
我有一张简单的单通道(8位)位图,只有亮度数据,我想将它与现有的帧缓冲混合,就像Photoshop中的屏幕混合模式那样。所以源图的白色像素(255)应该保持不变,源图的50%灰色像素(128)应该使帧缓冲像素变亮50%,源图的黑色像素应该不做改变。我需要设置glColor4f吗?你们中的一些glBlendFunc专家能帮我吗?
2个回答

11

屏幕混合是 C = S + (1 - S) × D,所以你需要的是 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR)。如果你有一个 alpha 通道,只要保持图像数据是预乘格式,就仍然可以获得正确的结果。


让我看看,假设源是0.5的灰色像素。如果源是白色,则1.0 +(1-1.0)x 0.5确实是白色。如果源是0.5,则0.5 +(1-0.5)x 0.5确实是0.75。好的,很酷。黑色然后0.0 +(1-0)x 0.5是0.5,不变。太棒了,谢谢。 - Geri Borbás
所以glBlendfunc只是一个源乘数和目标乘数?似乎没有更困难的了。现在更清楚了,谢谢。您能告诉我glColor4f如何发挥作用吗? - Geri Borbás
哦,又是一个简短的问题。预乘意味着 RGB 值通过某种方式被 alpha 值预先乘以?因此,在合成过程中进行“alpha 除法”不会丢失 RGB 信息?像这样的东西?PNG 是预乘的吗?还是只有 TGA 是预乘的? - Geri Borbás
1
启用混合后,OpenGL ES 不会直接将 S 写入帧缓冲区,而是写入 C = S × Sfactor + D × Dfactor。其中 D 是当前帧缓冲区中的值,并且您可以通过传递给 glBlendFunc 的参数来选择 Sfactor 和 Dfactor。glColor4f 设置当前顶点颜色,当您没有设置和启用颜色数组时使用该颜色。当前顶点颜色最初为 (1, 1, 1, 1)。颜色实际上的作用取决于您如何配置纹理环境。默认情况下,它用于调制纹理的颜色。 - Pivot
预乘意味着颜色(R、G、B、A)表示为(R×A,G×A,B×A,A)。在合成过程中没有α除法,而是已经完成了通常在合成过程中要进行的其中一种乘法,这就是为什么预乘alpha的标准混合使用glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)而不是glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)。PNG未预乘,但TGA可以预乘。您可以通过将非预乘图像绘制到CGBitmapContext中来获取预乘图像数据,该上下文使用预乘表示。 - Pivot

0

这对于直接阿尔法透明度对我有效。

  • RGB 源 = SRC_ALPHA
  • 透明度源 = SRC_ALPHA
  • RGB 目标 = ONE
  • 透明度目标 = ONE_MINUS_SRC_ALPHA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接