Setting up integer texture and binding as image
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, width, height, depth, 0, GL_RGBA, GL_INT, NULL);



This is not an integer image format. It's an unsigned, normalized, fixed-point image format. For those, you use floating-point image/sampler variables. So for a 3D texture, you would use image3D, not iimage3D.

If you want a true signed integer format, you would do this:

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32I, width, height, depth, 0, GL_RGBA_INTEGER, GL_INT, NULL);


Note two changes. First, the internal format is GL_RGBA32I, which specifies a 32-bit-per-channel signed integer format. The second is the use of GL_RGBA_INTEGER for the pixel transfer format. Even though you're not actually performing a pixel transfer (since you're passing NULL), you still must use an appropriate format and type. And the _INTEGER formats must be used if you're transferring to/from a texture with an integer format.

When you do this, you must of course use the iimage3D and isampler3D types in your shaders.