将负值混合到帧缓冲区 0 opengl

Blend negative value into framebuffer 0 opengl

该程序将一堆东西渲染到使用无符号归一化纹理来存储数据的中间帧缓冲区中。中间帧缓冲区与默认帧缓冲区混合。用于渲染与帧缓冲区 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);
}

设置draw到framebuffer 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 混合。这很慢而且维护起来很麻烦。还有其他办法吗?

Is there a way to disable clamping of fragment shader outputs to [0, 1]?

让我引用 OpenGL 4.6 Core Profile Specification17.3.6 混合 部分(强调我的):

If the color buffer is fixed-point, the components of the source and destination values and blend factors are each clamped to [0, 1] or [−1, 1] respectively for an unsigned normalized or signed normalized color buffer prior to evaluating the blend equation. If the color buffer is floating-point, no clamping occurs. The resulting four values are sent to the next operation.

因此您可以使用 *16F*32F 格式之一来摆脱限制。

I know that there is not a way to render to a signed normalized texture, so maybe there is an OpenGL limitation that prevents this.

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