Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL中的平滑可逆加/减亮度混合_Opengl_Alphablending_Blending_Pyopengl - Fatal编程技术网

OpenGL中的平滑可逆加/减亮度混合

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的符号和大小,我可以通过棋盘纹理平

我正在尝试执行一个相当具体的混合操作,但它似乎应该相对简单。我在背景上显示一个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
的符号和大小,我可以通过棋盘纹理平滑地改变背景调制的大小和极性

给你一个图形化的例子:

使用
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:使用
    (GL\u FUNC\u ADD)
    并将alpha设置为w


  • 对于WWW,您的目标是什么版本的GL?不再支持亮度纹理(3.1+不兼容)。你可以(相当老套地)使用深度纹理来获得单个组件纹理,其中
    r
    g
    b
    具有相同的值,并且
    a
    为常数1.0,或者使用
    GL_RED
    g
    b
    将未定义,
    a
    将为1.0).既然你说想要签名颜色,我就排除深度纹理。您可能需要
    GL\u R8\u snrom
    和一些swizzling(无论是扩展还是在实际的着色器中)。@AndonM.Coleman为了给您一些上下文,此代码是用PyOpenGL编写的一个相当深奥的科学软件的一部分,该软件已经充满了遗留的OGL API调用,因此,我并不特别担心
    GL\u亮度
    现在被弃用。我并不特别需要有符号的颜色-我所追求的是一种单一的混合模式,它允许我对背景图像的亮度进行加和减调制。这正是引入可编程管道的时候。@BartekBanachewicz我绝对愿意为此使用着色器,但我觉得这是不可能的,因为混合是通过片段着色器的输出完成的。这看起来几乎是正确的,但并不能完全解决我的问题。使用
    glBlendEquation(GL\u FUNC\u ADD)
    ,棋盘中“亮”方块下区域的亮度会增加(这是好的),但“暗”方块不会减少。类似地,使用
    glBlendEquation(GL\u FUNC\u REVERSE\u SUBTRACT)
    时,“亮”的方块会减少(这也很好),但“暗”的方块也不会被修改。这够清楚吗?我会试着给我的问题多加一点解释。@ali\m:嗯,它正是你给出的公式的模型。这个公式似乎不仅仅是你想要的:在黑色方块中,你的X_t值都是零,根据你的公式,这将导致目标值保持原样。也许你只是想要
    glBendFunc(GL\u SRC\u ALPHA,GL\u ONE\u减去\u SRC\u ALPHA)
    ,但这并不清楚。对不起,你是对的,这完全是我的错!我曾设想使用介于1和-1之间的
    GL_RGB_snrom
    纹理符号值,这将允许我同时增加和减少像素值(我认为Andon的评论暗示了这一点)。@ali_m:好的,在这种情况下,您可能仍然可以将混合与浮点帧缓冲区结合使用(见本标准第4.1.8节(混合)这基本上允许您使用负的alpha值。您可能需要另一个渲染过程来将结果转换为可以显示的standrad UNORM数据。很好-这似乎做到了!在我的真实代码中,我已经渲染到帧缓冲区,所以只需将帧缓冲区颜色附件更改为浮动格式,并使用
    glClampColor()
    功能关闭夹紧。