OpenGL GLSL采样器总是返回从0.0到1.0的浮点数吗?

Ted*_*ton 6 opengl glsl pyopengl

我创建了几个浮点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);
Run Code Online (Sandbox Code Playgroud)

然后我在着色器程序中交替地双重缓冲渲染/采样

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                       GL_TEXTURE_2D, texid[i], 0)
Run Code Online (Sandbox Code Playgroud)

...

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

...

    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;
    }
Run Code Online (Sandbox Code Playgroud)

...

    void main( void )
    {
        gl_FragColor = gl_Color;
    }
Run Code Online (Sandbox Code Playgroud)

请注意检查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;
    }
Run Code Online (Sandbox Code Playgroud)

...

    varying vec4 out_color;
    void main( void )
    {
        gl_FragColor = out_color;
    }
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 7

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

不,你没有.

glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_FLOAT, data);
Run Code Online (Sandbox Code Playgroud)

此语句不会创建浮点纹理.好吧,如果您使用OpenGL ES,也许它确实如此,但它肯定不会在桌面GL中使用.虽然我很确定OpenGL ES不允许你使用"4"作为内部格式.

在桌面GL中,第三个参数用于glTexImage2D定义图像格式.正是这个参数告诉OpenGL数据是浮点数,整数还是其他.当你使用"4"(你永远不应该这样做,因为这是一种指定内部格式的可怕方式.总是使用真正的内部格式),你告诉OpenGL你想要4个无符号规范化整数分量.

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

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

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data);
Run Code Online (Sandbox Code Playgroud)

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

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

3.3兼容性规范具有glClampColor定义顶点(和片段)颜色夹紧行为的函数.它只影响内置插件.亲身?我会避免它,根本就不使用内置的东西.

  • 如果glGetString(GL_VERSION)返回> 3.0,那么GL_RGBA32F应该可以工作.如果它返回<= 2.1,那么您需要检查GL_ARB_texture_float扩展名.如果存在,则使用GL_RGBA32F_ARB作为内部格式.或者检查GL_NV_float_buffer扩展名,如果存在,则使用GL_FLOAT_RGBA32_NV.如果这些扩展都不存在,那么您的驱动程序/卡不支持浮点. (3认同)