程序将一堆东西渲染到一个中间帧缓冲区中,该缓冲区使用无符号归一化纹理存储数据。中间帧缓冲区与默认帧缓冲区混合。用于渲染与帧缓冲区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
与负数混合。这是缓慢且难以维护的。还有其他办法吗?
答案 0 :(得分:1)
是否有一种方法可以禁止将片段着色器输出限制为[0,1]?
让我引用OpenGL 4.6 Core Profile Specification(强调我的)的 17.3.6混合部分:
如果颜色缓冲区是定点的,则源的组成部分以及目标值和混合因子分别针对无符号分别钳位到[0,1]或[-1,1]在评估混合方程之前,先进行标准化或有符号标准化的颜色缓冲区。 如果颜色缓冲区为浮点,则不会发生钳位。 四个值将发送到下一个操作。
因此,您可以使用*16F
或*32F
格式之一来消除限制。
我知道没有一种方法可以渲染为带符号的归一化纹理,因此可能存在OpenGL限制来阻止这种情况。
该规范将各种_SNORM
标记为 color-renderable 。但是,与此同时,规范并未将这些格式标记为渲染目标要支持的必需,因此实现可以允许您使用这种格式,但是他们不必这样做,所以是的,您不能以任何方式依赖它……