Why would you use Images instead of Framebuffers?
Image Load/Store is not intended to replace framebuffers. It's a feature that allows (relatively) arbitrary reading and writing to memory. So you would use images when you need to arbitrarily read and write to memory. You would use framebuffers when you're rasterizing primitives for rendering purposes.
The fact that you can build scenarios where you would use the latter in place of the former does not mean that this is the purpose of the feature.
What advantages do they offer?
Again, it's not meant to replace framebuffers. But the comparison is pretty simple.
A particular FS invocation cannot:
Choose what framebuffer texel(s) to write to. An FS invocation will only ever write outputs to the framebuffer texel(s) that map to its current fragment location. gl_FragCoord
is an input value; it is non-modifiable. An FS's outputs will either be discard or written to the framebuffer texel(s) corresponding to gl_FragCoord.xy
.
Yes, through point rasterization, you can select which fragment is being generated. But it isn't the fragment shader itself that's deciding this; it's whatever process wrote the vertex to the buffer that it's being read from. That is not under the direct control of the FS invocation itself.
Choose to write to multiple distinct framebuffer texel(s) locations. A fragment cannot cover multiple texels.
- Choose which output attachments in the framebuffer to write to. The decision of which fragment shader outputs will be written is made by the write mask state, which the FS has zero control over. An FS can choose to be discarded, but that discards all of its outputs.
- Choose to read from the current framebuffer texel(s) it is writing to. Blending is done by a fixed-function stage; the FS has zero control over this. The closest you can get is to employ some texture barrier gymnastics, but that's not something the FS can directly control.
- Choose to read from framebuffer texel(s) other than the one it's writing to. Even with texture barrier gymnastics, you cannot read from other people's texels.
Now granted, image load/store doesn't exactly make read/modify/write passes easy, due to incoherent memory access rules.
Of course, image load/store cannot handle (easily):
- Depth testing. Or at least, not in any way that is nearly as efficient as the rasterizer. The read/modify/write nature of the depth test makes this exceedingly tricky with image load/store. With a regular depth buffer however, this is trivial.
- Simple blending. Again, you can do it, but it's really hard, and far less efficient than the normal rendering process.