Search code examples
copenglglslshaderopengl-4

OpenGL usampler2d value cannot be divided


I've been writing GLSL shaders, and using an integer texture (GL_RED) to store values in the shader. When I attempt to divide a value taken from the usampler2D texture, it stays the same. The following is the minimal reproducible shader.

#version 440

in vec2 uv;
out vec3 color;

layout (binding = 1) uniform usampler2D tm_data;

void main(){
  float index = texture(tm_data, uv).r;
  float divisor = 16.0f
  color = vec3(index / divisor, 0, 0);
}

The rendered red value is always 1.0 regardless of a way i try to divide or mutate the index value.

When the sampler is changed to a normalized one (sampler2D) the color manipulation works as expected

#version 440

in vec2 uv;
out vec3 color;

layout (binding = 1) uniform sampler2D tm_data; //Loads as normalized from [0,255] to [0,1]

void main(){
  float index = texture(tm_data, uv).r * 255.0f; //Convert back to integer approximation
  float divisor = 4.0f
  color = vec3(index / divisor, 0, 0); //Shade of red now appears considerably darker
}

Does anyone know why this unexpected behaviour happens?

The tm_data texture is loaded as GL_RED -> GL_RED The OpenGL version used is 4.4 There is no framework being used (no sneaky additions), everything is loaded using gl function calls.


Solution

  • For the use of usampler2D, the internal format has to be a unsigned integral format (e.g. GL_R8UI). See Sampler types.
    If the internal format is the basic format GL_RED, then the sampler type has to be sampler2D.
    Note, sampler* is for the use of floating point formats, isampler* for signed integral formats and usampler* for unsigned integral formats.
    See OpenGL Shading Language 4.60 Specification - 4.1.7. Opaque Types and OpenGL Shading Language 4.60 Specification - 8.9. Texture Functions