该程序将一堆东西渲染成一个中间帧缓冲区,它使用无符号规范化纹理来存储数据。中间帧缓冲区与默认帧缓冲区混合。用于使用帧缓冲区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]范围内。预期的结果是从先前的帧缓冲内容中减去中间色。实际结果是黑色与正确的alpha与帧缓冲区0混合,这表明fragColor
在某处被钳位到[0,1]而负面部分被丢弃。
有没有办法禁用片段着色器输出到[0,1]的钳位?
我知道没有办法渲染到有符号的规范化纹理,所以可能有一个OpenGL限制可以防止这种情况。我想到的替代方案是做两个渲染过程,一个将负位渲染为中间,另一个将正位渲染到另一个中间。最后,与GL_FUNC_ADD
积极混合,与GL_FUNC_REVERSE_SUBTRACT
积极混合。维护缓慢且繁琐。还有其他方法吗?
有没有办法禁用片段着色器输出到[0,1]的钳位?
让我引用第17.3.6节OpenGL 4.6 Core Profile Specification的混合(强调我的):
如果颜色缓冲区是定点的,则在评估之前,对于无符号规范化或带符号的规范化颜色缓冲区,源和目标值以及混合因子的分量将分别钳位到[0,1]或[-1,1]。混合方程。如果颜色缓冲区是浮点,则不会发生钳位。生成的四个值将发送到下一个操作。
因此,您可以使用*16F
或*32F
格式中的一种来摆脱夹紧。
我知道没有办法渲染到有符号的规范化纹理,所以可能有一个OpenGL限制可以防止这种情况。
该规格标志着各种_SNORM
颜色可渲染。但是,与此同时,规范并未将这些格式标记为渲染目标所需的格式,因此实现可以允许您使用这种格式,但它们不需要,所以是的,您不能以任何方式解决这个问题......