0
\$\begingroup\$

I am trying to write a code for rendering a object with material properties (diffuse and specular). I am trying to use textures to pass float data to the vertex shader (I am accessing the textures in vertex shader). I have two textures with 7 miplevels each to pass data pertaining to specular reflections. I am using texelFetch to access the data. But if the level of the texture is greater than 0, then the value returned by texelFetch is invariably 0. Here is the code used to setup the textures in c++.

glGenTextures(1,&textures[1]);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
for(int mipLevel = 0; mipLevel < 7; mipLevel++)
{
    glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_R32F, 129, 129, 0, GL_RED, GL_FLOAT, specularTextures[mipLevel]);
    delete[] specularTextures[mipLevel];
}

As one can see I am using only the Red channel to pass the data. Now in vertex shader code I access the texture.

#version 450 core
layout (location = 0) in vec4 aVertex;
layout (location = 1) in vec4 aNormal;
layout (location = 2) in vec4 diffuseAlbedo;
layout (location = 3) in vec4 specularAlbedo;
layout (location = 4) in ivec4 brdfIndices[5];
layout (location = 9) in vec4 brdfWeights[5];

out vec4 ourColor;

uniform mat4 projection;
uniform mat4 view;
uniform vec3 camCenter;

uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture1;
uniform sampler2D specularTexture2;

int main()
{
    gl_Position = projection * view * aVertex;
    float value = texelFetch(specularTexture1, ivec2(10,10), 1).r;
    ourColor = vec4(vec3(value),1);
}

No matter what index I use to access the texture with level greater than 0 ( 1 in this case) I get value = 0. But if the level is 0 I am getting correct value. I tried to look online but no one was facing the similar problem, so I am guessing it is some kind of silly mistake.

Note: I am binding the textures everytime I am rendering.

\$\endgroup\$
  • \$\begingroup\$ Is that texetFetch typo only here or in your real code too? \$\endgroup\$ – Tyyppi_77 May 17 '18 at 6:27
  • \$\begingroup\$ My bad, it is only here. \$\endgroup\$ – Aditya May 17 '18 at 6:28
1
\$\begingroup\$

Section 11.1.3.2 (Texel Fetches) of the OpenGL specification (I'm using 4.4 for reference) explains this; you must use a mipmapped minification filter to access any LOD other than the base level.

Unlike filtered texel accesses, texel fetches do not support LOD clamping or any texture wrap mode, and require a mipmapped minification filter to access any level of detail other than the base level.

Also:

Texel fetches with incorrect parameters or state occur under any the following conditions ... the computed level of detail is not the texture’s base level and the texture’s minification filter is NEAREST or LINEAR.

And:

In all the above cases, if the context was created with robust buffer access enabled, the result of the texture fetch is zero, or a texture source color of (0, 0, 0, 1) in the case of a texel fetch from an incomplete texture. If robust buffer access is not enabled, the result of the texture fetch is undefined in each case.

So this is wrong:

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

But this is correct:

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
\$\endgroup\$
  • \$\begingroup\$ I tired changing the min filter setting to GL_NEAREST_MIPMAP_NEAREST, after changing even values from base level are also 0. I use GLFW to create context, and default setting is with robustness not enabled. \$\endgroup\$ – Aditya May 17 '18 at 10:13
  • \$\begingroup\$ The same section also states that the fetches might be incorrect if the texture is not complete (by that I take that they are talking about mipmap complete). In my case the dimension of all the levels are 128X128, and according to section 8.17 that means that the texture is not complete. I guess this is the reason in my case. But now that leads to another problem for me, I have 14 textures in that case and using 14 different textures might become really cumbersome in the code. \$\endgroup\$ – Aditya May 17 '18 at 10:43
  • \$\begingroup\$ Aditya - yes, that is incorrect in every version of every API; each mip level must be half the size (round down) of the previous. You probably actually want an array texture instead. \$\endgroup\$ – Maximus Minimus May 17 '18 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.