将负值混合到framebuffer 0 opengl中

时间:2019-02-25 20:05:05

标签: opengl-es framebuffer blending

程序将一堆东西渲染到一个中间帧缓冲区中,该缓冲区使用无符号归一化纹理存储数据。中间帧缓冲区与默认帧缓冲区混合。用于渲染与帧缓冲区0混合的中间物的像素着色器如下:

#version 300 es

precision mediump float;

out vec4 fragColor;

in vec2 texCoords;

uniform sampler2D textureToDraw;

void main()
{
    vec4 sampleColor = texture(textureToDraw, texCoords);
    fragColor = vec4(sampleColor.rgb * -1.0, sampleColor.a);
}

设置绘制到帧缓冲区0的代码如下:

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

// Draw the intermediate using the pixel shader above and a quad

fragColor的rgb分量将在[-1,0]范围内。预期结果是从先前的帧缓冲区内容中减去中间颜色。实际结果是将黑色与帧缓冲区0的正确alpha混合,这表明fragColor固定在某个位置的[0,1]处,并且排除了负数部分。

是否有一种方法可以禁止将片段着色器输出限制为[0,1]?

我知道没有一种方法可以渲染为带符号的归一化纹理,因此可能存在OpenGL限制来阻止这种情况。我正在考虑的另一种方法是进行两次渲染过程,一个将负位渲染到一个中间对象,另一个将正位渲染到另一个中间对象。最后,将GL_FUNC_ADD与正数混合,并将GL_FUNC_REVERSE_SUBTRACT与负数混合。这是缓慢且难以维护的。还有其他办法吗?

1 个答案:

答案 0 :(得分:1)

  

是否有一种方法可以禁止将片段着色器输出限制为[0,1]?

让我引用OpenGL 4.6 Core Profile Specification(强调我的)的 17.3.6混合部分:

  

如果颜色缓冲区是定点的,则的组成部分以及目标值和混合因子分别针对无符号分别钳位到[0,1]或[-1,1]在评估混合方程之前,先进行标准化或有符号标准化的颜色缓冲区。 如果颜色缓冲区为浮点,则不会发生钳位。   四个值将发送到下一个操作。

因此,您可以使用*16F*32F格式之一来消除限制。

  

我知道没有一种方法可以渲染为带符号的归一化纹理,因此可能存在OpenGL限制来阻止这种情况。

该规范将各种_SNORM标记为 color-renderable 。但是,与此同时,规范并未将这些格式标记为渲染目标要支持的必需,因此实现可以允许您使用这种格式,但是他们不必这样做,所以是的,您不能以任何方式依赖它……