[SOLVED] Shader imageLoad always returns black

Just for sanity’s sake, is this the correct way to create a 3D texture?

Image img = new Image(format, width, height, depth,
        new ArrayList<>(depth), colorSpace);
Texture3D tex = new Texture3D(img);

I suspect this might be incorrect, because whenever I read from the texture, the pixel is always returning as black, even though I definitely did write to the texture.

…then why not show that part, too?

layout(RGBA8) uniform image3D m_VoxelMap;
uniform int m_GridSize;

varying vec3 vPosition;

void main() {

    gl_FragColor = vec4(vPosition, 1.0);
    vec4 result = vec4(1.0, 1.0, 1.0, 1.0);
    imageStore(m_VoxelMap, ivec3(m_GridSize * vPosition), result);
   
}

vPosition is a vector between 0 and 1. I have confirmed this by outputing it through gl_FragColor. m_GridSize is the width, height, and depth of the 3D texture m_VoxelMap (which is a cube in my case).

The shader is definitely running, too.

Edit: also, here is the shader I’m using to test the contents of m_VoxelMap on a fullscreen quad:

layout(RGBA8) uniform image3D m_VoxelMap;
uniform float m_Slice;
varying vec2 texCoord;

void main() {
    ivec3 size = imageSize(m_VoxelMap);
    gl_FragColor = imageLoad(m_VoxelMap, ivec3(size * vec3(texCoord, m_Slice)));
}

m_Slice is a value between 0 and 1 which I continually update to scan the contents of m_VoxelMap.

Edit2: I really just want to know if I’m creating the 3D texture correctly. I can otherwise debug things on my end.

i might be misunderstanding, but at first glance it looks like you could be passing a generally initialized vec4 (result) as a temp ‘store’ parameter, where (i think) imageStore takes that vec4 as the actual data to be formatted into a texel and stored within m_VoxelMap.

…unless m_VoxeMap is being overwritten elsewhere afterward.

edit:
i could be wrong as result being all 1.0 would likely store opaque white texels, rather than the black being read.

There might be more than one correct way.

That said, I would start by studying jme3-examples:

1 Like

A few hints for using imageStore()

  1. any store operations before discard() are still executed
  2. i think that you have to use glMemoryBarrier before you read from the texture. ( unsure if it only applies to compute shaders or not )

How have you veryified that the writeoperation takes actually place?

1 Like

I managed to solve this last night. The problem was that imageLoad and imageStore won’t work unless the texture is additionally bound with glBindImageTexture. Things were setup correctly on my end, it’s just that GLRenderer only binds textures with glBindTexture. I’ve submitted a PR that addresses this.

Thanks for the suggestions guys. I am admittedly very new to this territory.

I’ve renamed this thread to be more search friendly.

3 Likes