# What is the difference between a Sampler and an Image variables in GLSL?

Reading through some code about voxelization I found the following line in the fragment shader

layout (binding = 0, r32f ) coherent uniform writeonly image3D volumeTexture;

I have only used samplers in the past and have never seen image3D before.

I have read the entries about Sampler Varibles and Image Variables but I really don't grasp the differences, advantages/disadvantages between Sampler and Image.

Can someone help me pointing out what are the difference between these two types of variables and when should I used one over the other?

• The title refers to Image2D and the code and body refer to image3D. Does one of these need to be edited? Which one are you asking about? – trichoplax Sep 12 '16 at 18:16

Unlike samplers imageLoad (Load in HLSL) requires a texel coordinate (integer). This will load the value at that location only. The range of the coordinate can be (0,0) to (image width, image height). Because only an integer can be supplied no sampling is applied to blend between multiple texels (e.g. bilinear in 2D). I'd therefore assume it is a cheaper operation.

Image processing algorithms such as blurs often use image load so that discrete texel values can be processed.

Image and Samplers differ in many ways. Unlike Samplers, images can only be addressed with an integer coordinate that ranges from (0,0) to (x,y), where x and y are the width and height of the image. They support random access reads like texelFetch, and support no filtering as you're accessing raw texels. The most interesting thing with images is that they support read and write access, in Open GLES there are limitations, wherein an image may only be specified as readonly or writeonly, not both, in desktop GL though you may specify an image as read/write so that you can both read and write to that image in a single pass.

Using a sampler, if you wanted to write a color into it you'd have to use an FBO, then a second pass to consume that. With images, you can do this all in one pass by writing to the image and reading from it, you'd have to handle the synchronisation yourself of course. Images are very useful for image processing etc.

• Images creation is the same as texture, but it must be binded as image to image units. These are equivalent of "texture units".
• With them you can arbitrarily perform read/write/modify operations using imageStore/imageLoad or atomic operations at some coordinates. Unlike samplers these coordinates are in unsigned integer range.
• They do not need to be part of framebuffer color attachments to write into them. This is useful and simplify some techniques like injecting data into volume textures and is used in compute shaders. No need to use draw calls with buffer data upload.
• There is no mipmapping or texture filtering available when doing operation on texture binded as image.
• Is there a typo in the third bullet point? I'm guessing it should say "they do not need to be part of framebuffer color attachments to write into them"? – Nathan Reed Sep 14 '16 at 0:46
• Yes you are right. Hmm strange, I meant the opposite - edited. – narthex Sep 14 '16 at 9:05