PDA

View Full Version : uint texture data has incorrect values in glsl



chisser98
02-20-2018, 10:23 PM
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(deferredLightingT errainGeometryPassShaderProgram, "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?

arekkusu
02-20-2018, 10:41 PM
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).

chisser98
02-20-2018, 11:25 PM
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.

GClements
02-21-2018, 01:21 AM
Arreksu has already identified the main issue, however there is another issue:





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


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().