Can't make imageLoad(image3D) to work (texture(sampler3D) or imageLoad(image2D) OK)


I am trying to make my shader work with a read-only image3D uniform.

This is the way I create my image:

// Creation
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_3D, tex);
float data[sx*sy*sz] = 1.0f everywhere;
glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, sx,sy,sz, 0, GL_RED, GL_FLOAT, data);
glBindTexture(GL_TEXTURE_3D, 0);

Code that binds the image and performs the rendering:

// Render time
#define SLOT 0
glUniform1iARB(tex, SLOT);
glBindImageTexture(SLOT, tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
glUseProgram and draw call.

And now the shader code:

#version 420
layout(r32f) uniform image3D tex;

void main()
  float result = imageLoad(tex, ivec3(0,0,0)).x; // always 0.0f - why?
  gl_FragColor = vec4(result, 0, 0, 1);

Tried on both nVidia and AMD GL4 hardware, with latest drivers - same result: imageLoad().x always returns 0.0f.

If I change my code to use a sampler3D instead of image3D (and use texture() in the shader of course), things work fine. If I use an image2D, things are also fine (imageLoad(tex, ivec2) instead of ivec3).

There is something that I am missing in the 3D case for images, but what?


NB: I also tried GL_LUMINANCE instead of GL_RED in the glTexImage3D call, with no luck

glBindImageTexture(…, GLboolean layered, ) // this must be GL_TRUE for 3D textures or 2D arrays, to use them with 3 coords (sampler3D).

Also, there’s possible texture-incompleteness creeping-in. When creating the texture, try adding:


Hi Ilian,

I did try layered=GL_TRUE already, and it doesn’t work. All read values are 0.0f.

Tried to generate mipmaps - same result. Tried setting WRAP_R, S and T to GL_CLAMP_TO_EDGE, MIN and MAX_LOD to 0.

Tried dozens of things in two days, to no avail.

Is your line:

glUniform1iARB(tex, SLOT);

a forum post typo?
If not, tex should instead be the uniform location, rather than the texture id.

Hi Dan,

Yes it is a forum post typo, I’m doing result = glGetUniformLocationARB(prog, “tex”); then glUniform1iARB(result, SLOT);
result is valid and no GL error.

I figured it out. As things weren’t working, I switched to a smaller prototype application that we are using. I changed the value of layered to GL_TRUE in this prototype, and things were still not working. I posted the message to the forum after that. I realized later that the prototype was doing bad things. So I switched back to my main application code and changed the value of layered to GL_TRUE. Worked. Too bad I got mixed up so badly.
Thanks both of you for your help.