OpenGL GLSL采样器是否总是返回从0.0到1.0的浮点数? [英] Do OpenGL GLSL samplers always return floats from 0.0 to 1.0?

查看:294
本文介绍了OpenGL GLSL采样器是否总是返回从0.0到1.0的浮点数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've created a couple of floating point RGBA texture...

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);

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

and then I double-buffer render/sample into them alternately in a shader program

    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].但是,我的理解是纹理本身具有完整的浮点类型.

Notice the check for sample.r being greater than 1.1. This never happens. It seems that either the call to texture2D or the output of the fragment shader clamps the value of sample.rgb to [0.0..1.0]. And yet, my understanding is that the textures themselves have complete floating-point types in them.

有什么方法可以避免这种卡住吗?

Is there any way to avoid this clamping?

更新:

按照下面的说明,我已经修复了glTexImage2D()调用以使用GL_RGBA32F_ARB,但仍然无法从采样器中获得大于1.0的值.

As per instructions below, I've fixed my glTexImage2D() call to use GL_RGBA32F_ARB, but I still don't get a value greater than 1.0 out of the sampler.

更新2:

我刚刚尝试将纹理初始化为大于1.0的值,并且它起作用了! texture2d()返回大于1.0的初始值.那么也许这意味着问题出在片段着色器中,是否写入了纹理?

I just tried initializing the textures to values larger than 1.0, and it works! texture2d() returns the initial, > 1.0 values. So perhaps this means that the problem is in the fragment shader, writing to the texture?

更新3:

我尝试过更改着色器,并且可以:

I've tried changing the shaders, and this works:

    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却不起作用?

Why does using a custom varying work, but using the built-in varying gl_FrontColor/gl_Color not work?

推荐答案

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

I've created a couple of floating point RGBA texture...

不,你没有.

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

此语句不会创建浮点纹理.好吧,如果您使用的是OpenGL ES,也许可以,但是肯定不在台式机GL中.尽管我很确定OpenGL ES不允许您使用"4"作为内部格式.

This statement does not create a floating-point texture. Well, maybe it does if you're using OpenGL ES, but it certainly doesn't in desktop GL. Though I'm pretty sure OpenGL ES doesn't let you use "4" as the internal format.

在桌面GL中,glTexImage2D的第三个参数定义图像格式.正是 this 参数告诉OpenGL数据是浮点数,整数还是其他.当您使用"4"(您应该从不执行此操作,因为这是指定内部格式的一种糟糕方法.始终使用真实的内部格式)时,您会告诉OpenGL您希望将4个无符号的归一化整数分量.

In desktop GL, the third parameter to glTexImage2D defines the image format. It is this parameter that tells OpenGL whether the data is floating-point, integer, or whatever. When you use "4" (which you should never do, because it's a terrible way to specify the internal format. Always use a real internal format), you're telling OpenGL that you want 4 unsigned normalized integer components.

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

The last three parameters specify the location, format, and data type of the pixel data that you want to upload to the texture. In desktop GL, this has no effect on how the data is stored. You're just telling OpenGL what your input pixels look like. The OpenGL ES specification unwisely changes this. The last three parameters do have some effect on what the internal format of the data is.

无论如何,如果要使用32位浮点数,则应要求它们:

In any case, if you want 32-bit floats, you should ask for them:

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


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

Why does using a custom varying work, but using the built-in varying gl_FrontColor/gl_Color not work?

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

Because it's built-in. I haven't used built-in GLSL stuff in years, so I never even noticed that.

3.3兼容性规范具有函数glClampColor,该函数定义了顶点(和片段)颜色夹持行为.它仅影响内置功能.亲自?我会避免使用它,而根本不使用内置的东西.

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.

这篇关于OpenGL GLSL采样器是否总是返回从0.0到1.0的浮点数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆