Forward rendering is the process of computing a radiance value for a surface fragment directly from input geometry and lighting information. Deferred rendering splits that process into two steps: first producing a screen-space buffer containing material properties (a geometry buffer, or G-buffer) built by rasterizing the input geometry, and second producing a radiance value for each pixel by combining the G-buffer with lighting information.
Deferred rendering is often presented as an optimization of forward rendering. One explanation is that lighting is fairly expensive and if you have any overdraw then you are lighting pixels that will never be seen on screen, whereas if you store material properties into a G-buffer and light afterwards, you are only lighting a pixel that will actually appear on-screen. Is this actually an advantage of deferred, given that you can also do a depth pre-pass and then do a forward rendering pass with depth test set to
GL_EQUAL or the equivalent?
Deferred rendering also has the potential to schedule better on the GPU. Splitting one large warp/wavefront into a smaller geometry wavefront and then smaller lighting wavefronts later improves occupancy (more wavefronts in flight simultaneously). But you also end up with a lot more bandwidth use (writing out a large number of channels to the G-buffer, then reading them back in during lighting). Obviously the specifics here depend a lot on your GPU, but what are the general principles?
Are there other practical performance considerations when deciding between forward and deferred rendering? (Assume that we can use variations of each technique if necessary: i.e. we can compare tiled forward to tiled deferred as well.)