如何使用 glBlendFunc (OpenGL ES 1.x) 进行 Photoshop 的屏幕混合?

Posted

技术标签:

【中文标题】如何使用 glBlendFunc (OpenGL ES 1.x) 进行 Photoshop 的屏幕混合?【英文标题】:How to do something like Photoshop's screen Blending with glBlendFunc (OpenGL ES 1.x)? 【发布时间】:2010-07-15 08:51:29 【问题描述】:

我有一个简单的单通道(8 位)位图,只有亮度数据,我想将它与现有的帧缓冲区混合就像 Photoshop 中的屏幕混合模式一样。

所以源的白色像素 (255) 应该产生白色,源的 50% 灰色像素 (128) 应该产生 50% 的帧缓冲区像素,源的黑色像素应该不理会结果。我也必须设置 glColor4f 吗?

您中的一些 glBlendFunc 专家可以在这里帮助我吗?

【问题讨论】:

【参考方案1】:

画面混合是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,不变。很酷,谢谢,太好了。 所以 glBlendfunc 只是一个源乘数和一个目标乘数?似乎没有什么比这更困难的了。现在更清楚了,谢谢。你能告诉我 glColor4f 是如何发挥作用的吗? 哦,还有一个简短的问题。预乘意味着RGB值以某种方式被aplha值预乘?那么合成过程中的“alpha-divide”不会丢失 RGB 信息吗?像这样的东西? PNG是预乘的吗?还是只有 TGA? 启用混合后,OpenGL ES 不会直接将 S 写入帧缓冲区,而是写入 C = S × Sfactor + D × Dfactor。 D 是当前帧缓冲区中的值,您可以使用传递给 glBlendFunc 的参数选择 Sfactor 和 Dfactor。 glColor4f 设置当前顶点颜色,当您没有设置和启用颜色数组时使用该颜色。当前顶点颜色以 (1, 1, 1, 1) 开始。颜色的实际作用取决于您如何配置纹理环境。默认情况下,它用于调整纹理的颜色。 预乘表示颜色(R,G,B,A)表示为(R×A,G×A,B×A,A)。合成期间没有 alpha 除法——相反,合成期间通常进行的乘法之一已经完成,这就是为什么预乘 alpha 的标准混合使用 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) 而不是 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)。 PNG 没有预乘,但 TGA 可以。您可以通过将非预乘图像绘制到使用预乘表示的 CGBitmapContext 中来从非预乘图像中获取预乘图像数据。【参考方案2】:

这对我来说适用于 Straight alpha。

RGB 源 = SRC_ALPHA alpha 源 = SRC_ALPHA RGB 目标 = ONE alpha 目标 = ONE_MINUS_SRC_ALPHA

【讨论】:

以上是关于如何使用 glBlendFunc (OpenGL ES 1.x) 进行 Photoshop 的屏幕混合?的主要内容,如果未能解决你的问题,请参考以下文章

opengl:混合跨平台的结果不一致

如何在OpenGL中实现灰度渲染?

如何在opengl iphone中为纹理提供动画?

Jogl:如何在 com.jogamp.opengl.swt.GLCanvas 上制作透明背景?

OpenGL ES iOS 入门实例

openGL中的完全透明对象