uint texture data has incorrect values in glsl

Hello,

I’m trying to send unsigned integer texture data to my shader, however, all of my RGB values seem to be zero. My A values are something other than zero (I’m not sure exactly what they are).

My texture data is in the form of a std::vector<char> in C++. I set each entry in the vector to 2. The vector is of size 257 * 257 * 4.

This is how I create my texture:


	GLuint id;
	glGenTextures(1, &id);
	glBindTexture(GL_TEXTURE_2D, id);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 257, 257, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, &data[0]);
	glGenerateMipmap(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, 0);

After I use my shader program, I find the position of my texture variable in the shader and set it to texture unit 1.


	glUniform1i(glGetUniformLocation(deferredLightingTerrainGeometryPassShaderProgram, "terrainMapTexture"), 1);

When I actually bind my texture, I do it like so:


	glActiveTexture(GL_TEXTURE0 + 1);
	glBindTexture(GL_TEXTURE_2D, id);

My Vertex shader:


#version 440 core

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 pvmMatrix;
uniform mat3 normalMatrix;

layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 textureCoordinate;

uniform sampler2D heightMapTexture;

out vec3 Position;
out vec3 FragPos;
out vec2 TexCoords;
out vec3 Normal;

void main()
{
	Position = position;

	vec4 textureValue = texture(heightMapTexture, position.xz/256);
	float height = 5.5*(textureValue.a)-5;
	vec3 newPosition = vec3(position.x/16, height, position.z/16);
	
    vec4 worldPos = modelMatrix * vec4(newPosition, 1.0);
    FragPos = worldPos.xyz; 
    
    mat3 normalMatrix2 = transpose(inverse(mat3(modelMatrix)));
    Normal = normalMatrix2 * textureValue.rgb;
    
    TexCoords = position.xz/16;
    
    gl_Position = pvmMatrix * vec4(newPosition, 1.0);
}

My fragment shader:


#version 440 core

layout (location = 0) out vec3 gPosition;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec4 gAlbedoSpec;

in vec3 Position;
in vec2 TexCoords;
in vec3 FragPos;
in vec3 Normal;

uniform usampler2D terrainMapTexture; // <-- This is the texture
uniform sampler2D splatMapTexture0;
uniform sampler2D splatMapTexture1;
uniform sampler2D splatMapTexture2;

void main()
{
    // store the fragment position vector in the first gbuffer texture
    gPosition = FragPos;
    // also store the per-fragment normals into the gbuffer
    gNormal = normalize(Normal);
    
    uint whichTexture = texture(terrainMapTexture, Position.xz/256).r; // <-- This is where I am attempting to grab a uint from my texture
    
    if (whichTexture == 0) // <-- Always seems to be true
    {
		gAlbedoSpec.rgb = texture(splatMapTexture0, TexCoords).rgb;
	}
    else if (whichTexture == 1)
    {
		gAlbedoSpec.rgb = texture(splatMapTexture1, TexCoords).rgb;
	}
    else if (whichTexture == 2) // <-- I would expect it to be true here
    {
		gAlbedoSpec.rgb = texture(splatMapTexture2, TexCoords).rgb;
	}
    else
    {
		gAlbedoSpec.rgb = vec3(0.5f, 0.0f, 0.0f);
	}
    
    // store specular intensity in gAlbedoSpec's alpha component
    gAlbedoSpec.a = 0.1f; //texture(texture_specular1, TexCoords).r;
}

I have omitted some of the other textures and variables that I’m binding/passing in. They seem to be working properly.

Does anyone have any idea what I may be doing wrong?

The default texture parameters use linear filtering. Integer format textures are incomplete with linear filtering, so the sampler returns (0,0,0,1).

That was exactly it, thanks arekkusu!

For anyone interested, adding


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

after I had bound my texture solved the issue.

Arreksu has already identified the main issue, however there is another issue:

texture() uses implicit derivatives to determine the level-of-detail, and derivatives are undefined within non-uniform control flow. If the various splatMapTexture* textures use mipmaps, you’ll need to calculate either the derivatives or the level-of-detail prior to the conditional and use e.g. textureGrad() or textureLod().