8

我创建了几个浮点 RGBA 纹理......

glBindTexture( GL_TEXTURE_2D, texid[k] );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA,
             GL_FLOAT, data);

然后我在着色器程序中交替地对它们进行双缓冲渲染/采样

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                       GL_TEXTURE_2D, texid[i], 0)

...

    state_tex_loc = glGetUniformLocation( program, "state_tex" )
    glUniform1i( state_tex_loc, 0 )
    glActiveTexture( GL_TEXTURE0 )
    glBindTexture( GL_TEXTURE_2D, texid[1-i] )

...

    void main( void )
    {
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
        vec2 sample_pos = gl_Vertex.xy / vec2( xscale, yscale );
        vec4 sample = texture2D( state_tex, sample_pos.xy );
        sample.rgb = sample.rgb + vec3( 0.5, 0.5, 0.5 );
        if ( sample.r > 1.1 )
            sample.rgb = vec3( 0.0, 0.0, 0.0 );
        gl_FrontColor = sample;
    }

...

    void main( void )
    {
        gl_FragColor = gl_Color;
    }

注意检查sample.r是否大于 1.1。这永远不会发生。似乎texture2D片段着色器的调用或输出将 sample.rgb 的值钳制为 [0.0..1.0]。然而,我的理解是纹理本身具有完整的浮点类型。

有什么办法可以避免这种夹紧?

更新:

按照下面的说明,我已经修复glTexImage2D()了使用 GL_RGBA32F_ARB 的调用,但我仍然没有从采样器中得到大于 1.0 的值。

更新 2:

我刚刚尝试将纹理初始化为大于 1.0 的值,它可以工作!texture2d()返回初始值 > 1.0。所以也许这意味着问题出在片段着色器中,写入纹理?

更新 3:

我试过改变着色器,这很有效:

    varying vec4 out_color;
    void main( void )
    {
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
        vec2 sample_pos = gl_Vertex.xy / vec2( xscale, yscale );
        vec4 sample = texture2D( state_tex, sample_pos.xy );
        sample.rgb = sample.rgb + vec3( 0.5, 0.5, 0.5 );
        if ( sample.r > 1.1 )
            sample.rgb = vec3( 0.0, 0.0, 0.0 );
        out_color = sample;
    }

...

    varying vec4 out_color;
    void main( void )
    {
        gl_FragColor = out_color;
    }

为什么使用自定义可变工作,但使用内置可变 gl_FrontColor/gl_Color 不起作用?

4

1 回答 1

7

我创建了几个浮点 RGBA 纹理......

不,你没有。

glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_FLOAT, data);

此语句不创建浮点纹理。好吧,如果您使用的是 OpenGL ES,也许它会这样做,但在桌面 GL 中肯定不会。虽然我很确定 OpenGL ES 不允许您使用“4”作为内部格式。

glTexImage2D在桌面 GL 中,定义图像格式的第三个参数。正是这个参数告诉 OpenGL 数据是浮点数、整数还是其他。当你使用“4”时(你永远不应该这样做,因为它是一种指定内部格式的糟糕方法。总是使用真正的内部格式),你告诉 OpenGL 你想要 4 个无符号归一化整数分量。

最后三个参数指定要上传到纹理的像素数据的位置、格式和数据类型。在桌面 GL 中,这对数据的存储方式没有影响。您只是在告诉 OpenGL 您的输入像素是什么样的。OpenGL ES 规范不明智地改变了这一点。最后三个参数确实对数据的内部格式有一些影响。

无论如何,如果您想要 32 位浮点数,您应该要求它们:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data);

为什么使用自定义可变工作,但使用内置可变 gl_FrontColor/gl_Color 不起作用?

因为它是内置的。多年来我没有使用过内置的 GLSL 东西,所以我什至从未注意到这一点。

The 3.3 compatibility spec has a function glClampColor that defines vertex (and fragment) color clamping behavior. It only affects the built-ins. Personally? I'd avoid it and just not use built-in stuff at all.

于 2012-02-22T16:53:53.577 回答