我正在尝试执行一个相当具体的混合操作,但似乎它应该相对简单。我在背景上显示亮度纹理,其alpha值为1.
例如,这可能是另一张图片上的简单棋盘:
我希望纹理根据以下内容线性增加/减少背景的亮度:
(R_b + R_t * w, G_b + G_t * w, B_b + B_t * w, 1.0)
其中*_b
是背景像素值(介于0和1之间),*_t
是重叠纹理的有符号像素值(介于-1和1之间),w
是加权参数也可以在-1和1之间变化。目标是通过改变w
的符号和幅度,我可以通过棋盘纹理平滑地改变背景调制的幅度和极性。
为您提供一个图形示例:
使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
只是改变叠加层的alpha值并不能完全符合我的要求,因为我无法使用负的alpha值来反转叠加层的极性。
有没有办法使用固定管道进行这种类型的线性加法/减法混合,或者如果失败,是否可以使用着色器实现这一点?
为了进一步澄清,我添加了一个粗略的PyOpenGL示例,说明了我正在尝试做的事情here。
要完全清楚,如果w > 0
,我想增加我棋盘上 white 方块内每个像素的亮度,降低黑色方块内每个像素的亮度。如果w < 0
我想做相反的事情。
derhass 的答案非常接近我正在寻找的内容,但只会影响白色方块中的像素,而不会影响黑色方块:
人类在判断绝对亮度方面很糟糕,但如果我将叠加层的颜色设置为红色(glColor4f(1., 0., 0., 0.25)
),则差异会更明显:
如您所见,这会导致在白色方块中添加/减去红色,但不会改变黑色方块。
答案 0 :(得分:1)
我认为你可以使用GL的混合,只要你的w
参数不会因每个像素而变化,但只是覆盖纹理的整个绘制调用的全局(正如你的图像所暗示的那样)。您只需根据w
:
将混合因子设置为glBlendFunc(GL_SRC_ALPHA,GL_ONE)
和
对于w&gt; = 0:使用glBlendEquation
(GL_FUNC_ADD)
并将alpha设置为w
对于w&lt; 0:使用glBlendEquation
(GL_FUNC_REVERSE_SUBTRACT)
并将alpha设置为-w
如前所述,这也将修改输出的alpha分量,但你希望它是1.0。正如您所说,渲染背景时,您的frambeuffer已经alpha = 1。因此,您可以使用glBlendFuncSeparate
(GL_SRC_ALPHA,GL_ONE,GL_ZERO,GL_ONE)
与上述公式结合使用,将结果alpha设置为目标中的{,A_b
。
事实证明,问题中的公式不是理想的行为,并且假设每次绘制调用只需要GL_FUNC_ADD
或 GL_FUNC_REVERSE_SUBTRACT
但是,如果使用浮点颜色缓冲区(ARB_color_buffer_float
),则可以使用负的alpha值。
如果颜色缓冲区是定点的,则源和的组件 目标值和混合因子各自被钳位到[0; 1]或 [-1; 1]分别用于无符号归一化或有符号归一化 在评估混合方程之前的颜色缓冲区。如果颜色 缓冲区是浮点数,不会发生钳位。由此产生的四个 值将被发送到下一个操作。
请注意,此扩展程序会引入glClampColor()
功能,并定义目标GL_CLAMP_READ_COLOR
,GL_CLAMP_VERTEX_COLOR
和GL_CLAMP_FRAGMENT_COLOR
。后两者在现代GL中已弃用,仅与已弃用的固定功能管道相关。