使用纹理更改帧部分的 alpha 值

Posted

技术标签:

【中文标题】使用纹理更改帧部分的 alpha 值【英文标题】:Changing alpha value on portions of the frame with a texture 【发布时间】:2015-03-10 15:28:34 【问题描述】:

我正在使用 OpenGL 开发 2D 绘画应用程序。与其他堆栈溢出一样,我正在努力解决的部分是橡皮擦功能。这是一个使用 OpenGL 3.2 的 OS X 应用程序。

其他人建议使用我已经实现的模板缓冲区。但是,据我所知,模板缓冲区是一个硬掩码——通过或失败——没有任何处理 alpha 级别的能力。如果我错了,请纠正我。

笔画是通过沿点路径应用纹理来创建的。我的画笔片段着色器看起来像这样。我正在为黑色和 alpha 画笔纹理应用颜色。

uniform sampler2D tex;
uniform vec4 color;
out vec4 outColor;

void main() 
    outColor = mix( vec4(color.rgb,0), vec4(color.rgb,1), texture(tex,gl_PointCoord));

在我的理想世界中,橡皮擦只会更新帧的 alpha 值,根据擦除纹理使像素不那么明显。使用 glBlendFunc() 似乎应该可以做到这一点,但我尝试了一堆组合,但没有任何效果。

我的画笔纹理是这样的。此处显示为灰色背景,但实际的 PNG 只是黑色和 alpha。

  

使用以下混合函数:

刷涂:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

擦除绘画:

glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);

我得到了这个效果,显然不是我想要的。我已经尝试了我在 SO 上找到的所有推荐的 glBlenFunc 组合,但都没有给我想要的结果。我错过了什么?

  

【问题讨论】:

我知道将背景颜色绘制为“擦除”很容易,但这不适用于多层和透明度。 出于所有意图和目的,模板缓冲区是通过/失败。较新的硬件允许您从着色器中读取它,这将允许您使用 256 个值来做任何您想做的事情。但这实际上完全取决于混合 - 我 认为 你真正想要的是 glBlendFuncSeparate (...) 判断 “在我的理想世界中,橡皮擦只会更新框架的 alpha 值".如果将 RGB 和 A 混合功能分开,则可以在混合 A 时保持 RGB 不变。 问题是,虽然...更新帧缓冲区中的 alpha 值不会影响画笔颜料的混合,因为帧缓冲区是 目标 而不是来源。您的其他混合功能仅依赖于源 alpha。 画笔颜料是在擦除笔划之前绘制的,所以画笔颜料混合是否重要?除非我误解了颜色缓冲区的工作原理。从逻辑上讲,在擦除笔划发生之后出现的画笔笔划不应受到擦除笔划的影响。 有人问一个相关的 OpenGL 问题是这样提出的:“如果源 RGBA 是 (r2, g2, b2, a2) 而目标是 (r1, g1, b1, a1)。我想要最终的值为 (r1, g1, b1, a2)。我该如何实现?" 【参考方案1】:

解决方法是使用混合函数 GL_ZERO、GL_ONE_MINUS_SRC_ALPHA。我将画笔绘制和擦除笔触渲染到纹理,然后将该纹理渲染到我的帧缓冲区。白色轮廓的修复是将我的第一次渲染设置为 glClearColor(0,0,0,1)

【讨论】:

以上是关于使用纹理更改帧部分的 alpha 值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QOpenGLTexture 中创建带 alpha 的纹理?

在openGL中。如何将纹理的一部分复制到另一个纹理

OpenGL中怎么使用压缩纹理?

更改导航栏的 alpha 值

渲染到纹理时出现黑屏

线条不会在具有完全黑色纹理的屏幕外帧缓冲区上渲染