OpenGL中的平滑可逆加/减亮度混合
我正在尝试执行一个相当具体的混合操作,但它似乎应该相对简单。我在背景上显示一个alpha值为1的亮度纹理 例如,这可能是另一个图像上方的简单棋盘: 我希望纹理根据以下条件线性增加/减少背景亮度:OpenGL中的平滑可逆加/减亮度混合,opengl,alphablending,blending,pyopengl,Opengl,Alphablending,Blending,Pyopengl,我正在尝试执行一个相当具体的混合操作,但它似乎应该相对简单。我在背景上显示一个alpha值为1的亮度纹理 例如,这可能是另一个图像上方的简单棋盘: 我希望纹理根据以下条件线性增加/减少背景亮度: (R_b + R_t * w, G_b + G_t * w, B_b + B_t * w, 1.0) 其中,*\u b是背景像素值(介于0和1之间),*\u t是叠加纹理的有符号像素值(介于-1和1之间),w是一个权重参数,也可以在-1和1之间变化。目标是通过改变w的符号和大小,我可以通过棋盘纹理平
(R_b + R_t * w, G_b + G_t * w, B_b + B_t * w, 1.0)
其中,*\u b
是背景像素值(介于0和1之间),*\u t
是叠加纹理的有符号像素值(介于-1和1之间),w
是一个权重参数,也可以在-1和1之间变化。目标是通过改变w
的符号和大小,我可以通过棋盘纹理平滑地改变背景调制的大小和极性
给你一个图形化的例子:
使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去_SRC_ALPHA)
仅仅改变覆盖的ALPHA值并不能达到我想要的效果,因为我不能使用负ALPHA值来反转覆盖的极性
有没有一种方法可以使用固定管道进行这种类型的线性加法/减法混合,如果没有,是否可以使用着色器实现这种混合
更新
为了进一步澄清,我添加了一个粗略的PyOpenGL示例来说明我要做的事情
更新2
要完全清楚,如果w>0
,我想增加棋盘上白色方块内每个像素的亮度,并降低黑色方块内每个像素的亮度。如果w<0
我想做相反的事情
derhass的答案与我想要的非常接近,但只影响白色方块中的像素,而不影响黑色方块中的像素:
人类在判断绝对亮度方面很糟糕,但是如果我将叠加的颜色设置为红色(glColor4f(1,0,0,0.25)
),差别会更明显:
如您所见,这将导致从白色方块中添加/减去红色,但不会更改黑色方块。我认为您可以使用GL的混合,只要您的
w
参数不会因像素而异,而只是覆盖纹理的整个绘制调用的全局(如您的图像所示)。您只需根据w
的符号设置混合方程:
将混合系数设置为glBlendFunc(GL\u SRC\u ALPHA,GL\u ONE)
,然后
- 对于w>=0:使用
并将alpha设置为w(GL\u FUNC\u ADD)
- 对于WWW,您的目标是什么版本的GL?不再支持亮度纹理(3.1+不兼容)。你可以(相当老套地)使用深度纹理来获得单个组件纹理,其中
,r
,g
具有相同的值,并且b
为常数1.0,或者使用a
(GL_RED
和g
将未定义,b
将为1.0).既然你说想要签名颜色,我就排除深度纹理。您可能需要a
和一些swizzling(无论是扩展还是在实际的着色器中)。@AndonM.Coleman为了给您一些上下文,此代码是用PyOpenGL编写的一个相当深奥的科学软件的一部分,该软件已经充满了遗留的OGL API调用,因此,我并不特别担心GL\u R8\u snrom
现在被弃用。我并不特别需要有符号的颜色-我所追求的是一种单一的混合模式,它允许我对背景图像的亮度进行加和减调制。这正是引入可编程管道的时候。@BartekBanachewicz我绝对愿意为此使用着色器,但我觉得这是不可能的,因为混合是通过片段着色器的输出完成的。这看起来几乎是正确的,但并不能完全解决我的问题。使用GL\u亮度
,棋盘中“亮”方块下区域的亮度会增加(这是好的),但“暗”方块不会减少。类似地,使用glBlendEquation(GL\u FUNC\u ADD)
时,“亮”的方块会减少(这也很好),但“暗”的方块也不会被修改。这够清楚吗?我会试着给我的问题多加一点解释。@ali\m:嗯,它正是你给出的公式的模型。这个公式似乎不仅仅是你想要的:在黑色方块中,你的X_t值都是零,根据你的公式,这将导致目标值保持原样。也许你只是想要glBlendEquation(GL\u FUNC\u REVERSE\u SUBTRACT)
,但这并不清楚。对不起,你是对的,这完全是我的错!我曾设想使用介于1和-1之间的glBendFunc(GL\u SRC\u ALPHA,GL\u ONE\u减去\u SRC\u ALPHA)
纹理符号值,这将允许我同时增加和减少像素值(我认为Andon的评论暗示了这一点)。@ali_m:好的,在这种情况下,您可能仍然可以将混合与浮点帧缓冲区结合使用(见本标准第4.1.8节(混合)这基本上允许您使用负的alpha值。您可能需要另一个渲染过程来将结果转换为可以显示的standrad UNORM数据。很好-这似乎做到了!在我的真实代码中,我已经渲染到帧缓冲区,所以只需将帧缓冲区颜色附件更改为浮动格式,并使用GL_RGB_snrom
功能关闭夹紧。glClampColor()