On Tuesday 01 February 2005 13:31, Timothy Miller wrote:
Daniel Phillips wrote:
By the way, is 1/W in the depth buffer going to be fixed point or floating point? I suggest keeping things simple and always using 24 or 32 bit fixed point. If 24 bit, the left over 8 bits can be used for stencil or alpha. Again, what the hardware does doesn't have to reflect the OpenGL state exactly, so long as the driver can make it appear to.
I was going to use float25 (16 bit mantissa), because it's not so easily predictable what the range of precision should be. No one's ever made any suggesion about what values 'd' might have, plus d is kinda just an artifact of the fact that I'm working in device coordinates. It's unfortunate that we have to waste bits on the exponent, but I'm not sure we have a choice.
The depth buffer doesn't need a sign bit because it's normalized, so float24 would be fine. But what is wrong with 6 bit exponent, 18 bit mantissa, just in the depth buffer?
Nothing, except that we won't do more than 16 mantissa bits as long as the multipliers are only signed 18-bit.
Do the math and you'll realize that the simplest way to perform the multiply is to denormalize the float (which involves adding the 1 bit on the left), so you get a 17-bit number. The highest bit is a sign, so we can't use that.
In my experience, a 16 bit depth buffer is not useful for much more than contrived demos. With a 1/W depth buffer, planes start to interpenetrate horribly as soon as the viewpoint recedes only a short distance, or else you have to place the front clipping plane unacceptably far away. This problem could be alleviated by using floating point 1/W in the depth buffer, though I suspect that would introduce a different and nastier plethora of precision artifacts, not to mention bloating up the hardware.
According to Hugh Fisher, our resident graphics professor on the list, a paper was published a while back that showed that W-buffering had demonstrably better results than Z-buffering. But it wasn't clear to me if they meant W or 1/W. (I didn't see the paper.)
I'm no graphics professor but I'll guess 1/W, which luckily is what has to be interpolated anyway. I'll also guess that the reason for the superiority is that you care more about precision for the parts of the scene closer to the viewpoint. On the other hand, closely spaced parallel planes far in the distance start to interpenetrate badly. On the third hand, such interpenetration can in theory be eliminated at the application level by feeding everything through a preprocessor first to eliminate obscured polygons. Maybe I'll manage to get some time to write such a preprocessor as a demonstration. It's much more stylish than just dumping everything into the card and letting the Z buffer sort it out.
I'm not worried about it. Trying to be overly clever on this project is practically impossible because OpenGL has so many requirements that are antithetical to being clever, at least in hardware.
While I'm rambling, I'll mention that the Quake engines don't do full Z buffering for scene geometry, they use Z fill instead. Hidden surfaces are handled with a BSP tree, and (at least for the software renderer) a scanline processor is used to eliminate pixel overdraw. Mobile objects are then rendered using normal Z buffering. This strategy is easier on memory bandwidth and eliminates the possibility of scene geometry depth buffer artifacts.
Anyhow, screw it. I'm going to do Z buffering, because that's what everyone wants.
Well, not me, but once again since it's an FPGA there's very little penalty for doing it one way and changing later.
There is and there isn't. There will come a point when I start optimizing, and some optimization choices may intertwine some things so tightly that making "simple" changes becomes a nightmare.
If there are any adjustments to the numbers which would improve precision, they can probably be substituted for Z.
Additionally, I'm going to store screen Z in the depth buffer, not
world Z, because I can't compute world Z in hardware without an even
greater precision loss.
It's never world Z in the screen buffer, Z always has to at least be rotated to view coordinates.
Terminology problem. My understanding is this:
- Object Z -- Z coordinates in space, before camera transform
- World Z -- Z coordinates in space, AFTER camera transform
- Screen Z -- Z coordinate that underwent the same perspective transform as X and Y.
Therefore, the question still hasn't been answered. _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
