Jump to content
  • Advertisement
  • entries
    41
  • comments
    137
  • views
    108559

Floating point depth buffers

Sign in to follow this  
cameni

1351 views

I had always thought that using a floating point depth buffer on modern hardware would solve all the depth buffer problems, in a similar way than the logarithmic depth buffer but without requiring any changes in the shader code, and having no artifacts and potential performance losses in their workarounds. So I was quite surprised when swiftcoder mentioned in this thread that he had found that the floating point depth buffer had insufficient resolution for a planetary renderer.

The value that gets written into the Z-buffer is value of z/w after projection, and it has an unfortunate shape that gives enormous precision to a very narrow part close to the near plane. In fact, almost half of the possible values lie within two times the distance of the near plane. In the picture below it's the red "curve". The logarithmic distribution (blue curve), on the other hand, is optimal with regards to object sizes that can be visible at given distance.


Floating point depth buffer should be able to handle the original z/w curve because the exponent part corresponds to the logarithm of the number.

However, here's the catch. Depth buffer values converge towards value of 1.0, or in fact most of the depth range gives values very close to it. The resolution of floating point around 1.0 is entirely given by the mantissa, and it's approximately 1e-7. That is not enough for planetary rendering, given the ugly shape of z/w.

However, the solution is quite easy. Swapping the values of far and near plane and changing the depth function to "greater" inverts the z/w shape so that it iterates towards zero with rising distance, where there is a plenty of resolution in the floating point.

I've also found an earlier post by Humus where he says the same thing, and also gives more insight into the old W-buffers and various Z-buffer properties and optimizations.

Update


I tried to compute the depth resolution of various Z-buffers for whole range from 0 to 10,000 kilometers. Here's the result (if I didn't make a mistake), showing the resolution at given distance (lower is better):




The red curve shows resolution of the logarithmic Z-buffer. It scales linearly with distance, what means that in the screen space it's constant. That's also the ideal behavior.

The blue curve shows the resolution of 32 bit floating point depth buffer with swapped far and near plane. The spikes are formed with each decrement of the exponent. Floating point depth buffer has worse resolution than the logarithmic one, but it should be still sufficient. The green line is for an ideal Z-buffer that has depth resolution of 0.12 millimeters at one kilometer. It also happens to be the worst case bound for the floating point depth buffer.
Sign in to follow this  


4 Comments


Recommended Comments

How does this compare to your previous post on the Logarithmic Depth Buffer, and Ysaneya's ideas on the subject?

Share this comment


Link to comment
Quote:
Original post by patrickvl
How does this compare to your previous post on the Logarithmic Depth Buffer, and Ysaneya's ideas on the subject?
I haven't tested it thoroughly yet, but as far as I can tell the floating point depth buffer with the reversed planes should be almost on par with the logarithmic one with respect to the resolution. It's also simpler to use, without bringing in the near-plane artifacts or eliminating fast-z by writing the depth in pixel shader as in the workaround.
But I shall test it more complexly later, and I also hope someone will evaluate it in their environment too.

Share this comment


Link to comment
I will slap this into my planetary renderer once I get back home - would likely simplify my codebase quite a bit.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!