【发布时间】:2014-06-04 06:18:04
【问题描述】:
我正在尝试执行一项相当具体的混合操作,但看起来应该相对简单。我在 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。
更新 2
完全清楚,如果w > 0,我想增加我棋盘上白色方块内每个像素的亮度,并减少 黑色方块内每个像素的亮度。如果w < 0 我想做相反的事情。
derhass 的答案非常接近我正在寻找的内容,但只影响白色方块中的像素,而不影响黑色方块中的像素:
人类在判断绝对亮度方面很糟糕,但如果我将叠加层的颜色设置为红色 (glColor4f(1., 0., 0., 0.25)),差异会更明显:
如您所见,这会导致从白色方块中添加/减去红色,但不会更改黑色方块。
【问题讨论】:
-
您的目标是哪个版本的 GL?不再支持亮度纹理(3.1+ 不兼容)。您可以(相当粗暴地)使用深度纹理来获得单分量纹理,其中
r,g,b具有相同的值并且a是常量 1.0 或使用GL_RED(g和b将是未定义的,a将是 1.0)。 -
既然你说想要签名颜色,我会排除深度纹理。您可能需要
GL_R8_SNORM和一些 swizzling(无论是扩展还是在实际着色器中)。 -
@AndonM.Coleman 为了给你一些背景信息,这段代码是用 PyOpenGL 编写的相当深奥的科学软件的一部分,它已经充满了遗留的 OGL API 调用,所以我并不特别担心
GL_LUMINANCE现在已弃用。我并不特别需要有符号的颜色 - 我所追求的是一种单一的混合模式,它允许我以加法和减法方式调制背景图像的亮度。 -
这正是引入可编程管道的时候。
-
@BartekBanachewicz 我绝对愿意为此使用着色器,但我的印象是这是不可能的,因为混合是对片段着色器的输出进行的。
标签: opengl alphablending blending pyopengl