Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

In many common AAA titles (Source engine games especially), when the player reaches an area 'un-catered' for, such as out of bounds, or noclipping under the map; a strange effect occurs on the screen (buffer tearing?).

It can be described as being similar to the trail of windows that Windows XP may leave behind a window being dragged whilst theres a system hang.

I can only postulate that the developers do not clear the color buffer when refreshing the screen?

Is that correct? If so, why?

share|improve this question
7  
BTW, this is often called the "Hall of Mirrors" effect or HOM. –  Nathan Reed Sep 25 '11 at 23:25
add comment

2 Answers 2

up vote 30 down vote accepted

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 pixel would be rendered over again. They developed many techniques for doing 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 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 anything that could possibly be written on frame 1. 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 color/depth 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 basically 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.

share|improve this answer
    
Is your last statement implying to never do the depth buffer alternating or? Great answer. –  Daniel Sep 26 '11 at 4:11
1  
@Daniel Yes. I clarified my post. –  Nicol Bolas Sep 26 '11 at 4:18
3  
Additionally skipping the clear on binning architectures (like most OpenGL ES chips) causes massive performance loss, as the graphics chip can't make assumptions on the color buffer state. –  Jari Komppa Sep 26 '11 at 9:01
add comment

Yes, you're right that the back buffer isn't being cleared.

Why is because (mostly) that it's faster to use a custom shader that ping-pongs depth values in opposite directions each frame and rely on the fact that your game always renders every pixel on the screen.

So for zero cost you save one buffer clear per frame.

share|improve this answer
1  
I don't know about depth ping-ponging; every engine I'm familiar with clears the depth/stencil buffer each frame. But aside from that, yes, if the game renders all the pixels (as it should), you don't need to clear the color buffer. –  Nathan Reed Sep 25 '11 at 23:26
    
Could you give an example for the shader, good answer otherwise. –  Daniel Sep 26 '11 at 0:41
1  
I realize that you're asking about recent engines, reading @NathanReed's comment is how many PC-only engines work now. The Z buffer twist is an older technique, I'll see if I can find a reference. Console engines will mostly clear all the color buffer too, even one pixel showing the HOM effect Nathan named will fail a title and force it to go through submissions all over again. –  Patrick Hughes Sep 26 '11 at 2:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.