Do OpenGL GLSL samples always return floats from 0.0 to 1.0?

I created a couple of RGBA floating point textures ...

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 double visualize the visualization / sample in them in the 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; } 

Note that the sample.r check exceeds 1.1. It never happens. It seems that either calling texture2D or the output of the fragment shader clamps the value of sample.rgb to [0.0..1.0]. And yet, I understand that the textures themselves have full floating point types in them.

Is there any way to avoid this clamp?

UPDATE:

Following the instructions below, I fixed my glTexImage2D() call to use GL_RGBA32F_ARB, but I'm still not getting a value greater than 1.0 from the sampler.

UPDATE 2:

I just tried initializing textures with values ​​in excess of 1.0, and it works! texture2d() returns initial values> 1.0. Perhaps this means that the problem is in the fragment shader, writing the texture?

UPDATE 3:

I 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; } 

Why is using custom muting work, but using the built-in mutable gl_FrontColor / gl_Color does not work?

+5
source share
1 answer

I created a couple of RGBA floating point textures ...

No, you didn’t.

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

This statement does not create a floating point texture. Well, maybe this is the case if you are using OpenGL ES, but this, of course, is not in the desktop GL. Although I am sure that OpenGL ES does not allow the use of "4" as an internal format.

On the GL desktop, the third parameter glTexImage2D determines the image format . It is this parameter that tells OpenGL whether the data is a floating point, integers, etc. When you use "4" (which you should never do because it is a terrible way to specify the internal format. Always use the real internal format), you tell OpenGL that you want 4 unsigned normalized integer components.

The last three parameters determine the location, format, and data type of the pixel data that you want to load into the texture . In desktop GL, this does not affect how data is stored. You just tell OpenGL what your input pixels look like. The OpenGL ES specification unreasonably changes this. The last three parameters have some effect on the internal data format.

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

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

Why is using custom muting work, but using the built-in mutable gl_FrontColor / gl_Color does not work?

Because it is built-in. I have not used GLSL embedded material for many years, so I have not even noticed this.

Compatibility Specification 3.3 has the glClampColor function, which defines the color capture behavior of vertices (and fragments). This only affects the built-in modules. Personally? I would avoid this and simply would not use inline material at all.

+7
source

All Articles