Once upon a time, clearing the color and depth buffers actually took time. Doing a clear meant that the graphics card would have to walk every pixel of the framebuffer and write a value to it.
Because of this, game developers found that it would be more efficient to simply assume that, every frame, you would write to every pixel. They developed many techniques for taking advantage of this.
The color buffer is the easiest to ignore. Less easy is the depth buffer, because it would be polluted with old data. So what they did was simple.
On frame 0, they would render with a glDepthRange
(or the D3D equivalent) of (0, 0.5), and they would use a glDepthFunc
of GL_LESS
(or GL_LEQUAL
). This means that the farthest depth value you would ever get in the depth buffer is 0.5. So the largest value in the depth buffer at the end of frame 0 is 0.5 (assuming you wrote to every pixel).
On frame 1, they would change the depth range to (1, 0.5). Notice that in this case, the near depth value is larger than the far depth. But they would also change the depth func to GL_GREATER
(or GL_GEQUAL
), which reverses the meaning of the depth test. Because the largest value in the depth buffer at this point is 0.5, everything you write will have a value larger than this. Since the depth test was reversed, this effectively means that whatever was written on frame 0 is now farther away than everything that frame 1 will write. At the end of frame 1, the smallest value in the depth buffer is now 0.5.
And then they repeat.
On any hardware made since around 2003, this is no longer an optimization. Indeed, it is a negative optimization. Clearing the depth buffer actually makes hardware faster. No, really.
Basically, what happens is that clearing buffers doesn't actually write anything. They store some bits in the GPU's caches that let the system know what are the color/depth values they have been cleared to. When the system tries to write to a cache line of the framebuffer, it doesn't bother to read what's there, because it already knows that it is a blank field of the clear color/depth value. If you try to blend with what's there or do a depth test, again, no need to read: it knows what value to blend/test with/against.
So every first read/modify/write that you do on each cache line after a clear is just a write. It's free.
Plus, having a jagged depth buffer can work against Hyper-Z/Hierarchial-Z/any Z-culling optimizations in hardware. Yes, your scene will work against those eventually as you add detail. But if your depth buffer is jagged from previous renderings, even if those background objects are in the background, it can affect the efficiency of Z-culling techniques. And that's not going to help performance.
So you should never do this depth reversal technique in modern games.
Note: Jari makes a good point on tile-based rendering architectures (as found in most mobile platforms). Not clearing the depth can make things unpleasant there too.