PDA

View Full Version : How do you enable a w-buffer?



CGameProgrammer
04-14-2002, 08:11 PM
Do you have to use an extension of some sort? In Direct3D it's really simple: m_Device->SetRenderState( D3DRS_ZENABLE, D3DZB_USEW ). I'm sure it's more complicated with OpenGL, but how do you do it? The Red Book does not even allude to the existence of w-buffers.

marcus256
04-14-2002, 10:02 PM
AFAIK OpenGL really only deals with a "depth buffer". It does not specifically say that it's Z or W (only that "very far away" = 1.0, and "very close" = 0.0). I have found no way to controlling the depth buffer format under OpenGL. Perhaps some drivers allow changing this on a global basis (in display settings under Windows, for instance).

CGameProgrammer
04-15-2002, 03:11 PM
Well, there's no option for me (with a GeForce2 Go) to select whether OpenGL uses a z-buffer or w-buffer. But I'm sure OpenGL must support this somehow, right?

cass
04-15-2002, 03:45 PM
There is probably an OpenGL extension for w-buffer support, but none that I'm aware of.

You could implement your own with the depth replace texture shaders on GeForce3 and GeForce4 Ti.

Thanks -
Cass

CGameProgrammer
04-15-2002, 04:55 PM
I have a GeForce2 which doesn't support pixel shaders, but anyway I'd want to support w-buffers on any card that allows it, not just cards that have pixel shading.

zed
04-15-2002, 05:19 PM
>>I have a GeForce2 which doesn't support pixel shaders, but anyway I'd want to support w-buffers on any card that allows it, not just cards that have pixel shading.<<

i dont believe all cards support it (even with d3d) so it looks like youre stuff with the zbuffer
which imho is a lot better than a wbuffer.
if u want more precision at far ranges of the zbuffer theres a few things u can do.
search this group for examples

CGameProgrammer
04-15-2002, 05:43 PM
I wasn't planning on requiring w-buffers, but I should allow it for all cards that support w-buffers without necessarily supporting pixel shading, was my point.

Anyway I read a tutorial online and discovered that w-buffer are inaccurate at close range, which is definitely Not Good. So I'll just stick with a z-buffer, I guess, and see how good/bad the w-buffer is in D3D.

marcus256
04-15-2002, 10:17 PM
It is my understanding that the precision of the W buffer is equal regardless of distance, while the precision of the Z buffer is better at close distances and worse at far distances. In general, you want the Z buffer behaviour (closer is more important).

Cass, when I was writing a Glide -> OpenGL wrapper, I was searching high and low for an OpenGL extension that allowed selection of depth buffer format (in Glide you can select W or Z), but I didn't find any.



[This message has been edited by marcus256 (edited 04-16-2002).]

CGameProgrammer
04-16-2002, 09:26 AM
You're right, Marcus; that's what I meant. The W-buffer is more inaccurate at close distances than the z-buffer. The inaccuracy is even throughout, since it's just the floating-point precision that limits it, but close-up it might be very noticeable. For the terrain it won't be noticeable, but for other objects it probably will.

cass
04-16-2002, 10:21 AM
CGameProgrammer,

Careful. W varies linearly in eye space, so if you stored it in fixed point, the accuracy is independent of the depths being resolved. If you store W in floating point, you *do* change the way precision is distributed. Floating point naturally packs more precision toward zero. That's why some people advocate having a floating point z buffer with a glDepthRange(1,0). The idea would be to try to balance the uneven distribution of the z buffer with the uneven precision distribution of floating point.

Thanks -
Cass

dorbie
04-16-2002, 11:28 AM
The relationship would seem arbitrary if you do this depending on where near and far clip planes landed.....but I suppose it's already arbitrary.

How about a floating point W buffer. You do still want and need more precision towards the viewer. FP W buffer would give a more consistent and pleasing depth precision distribution over a broader (and more typical) range of near and far clip values without the nasty side effects when you have the near clip too close to the eye, which is the real reason most people have precision problems with Z buffer.

[This message has been edited by dorbie (edited 04-16-2002).]

CGameProgrammer
04-16-2002, 01:30 PM
The w-buffer is *always* floating-point, which is why I was thinking of using it. W = 1/Z, so if W was an integer, it would always be zero.

cass
04-16-2002, 07:18 PM
CGameProgrammer,

There's nothing that says that w-buffering must be done in floating point. That may be the way it's done in Direct3D, but that doesn't mean it can't be done in fixed point.

Cass

CGameProgrammer
04-16-2002, 08:58 PM
Actually you're right, I was thinking of taking the inverse of an integer... but just as the floating-point Z coordinates are scaled to (0..65535) or (0..16777216), so too could the W-coordinates be converted to fixed point.

wimmer
04-16-2002, 11:48 PM
There's a paper about the various z-buffer and w-buffer precision issues (and the glDepthRange-hack cass talks about), it's called "Optimal Depth Buffer for Low-Cost Graphics Hardware" (look for this on Google). Might give some more insight...

Michael

dorbie
04-17-2002, 07:24 PM
The issue is how W is stored in the framebuffer and used for comparrison, not simply what comes off the transformed vertex.

As Cass says the stored representation is everything and a float representation isn't a given. That takes floating point fragment interpolators. It is wrong to describe a w buffer as linear if it is stored as a float.

My apologies to Cass, I never read your post fully when I wrote what I did. A fp W seems intuitively to have some inherently attractive properties, although perhaps a scaled fp 'linear' value between a zero near value and any programmable far value before you store to limited precision would permit almost complete control of precision throughout the 'linear' range.

It could be a lot of extra work though.


[This message has been edited by dorbie (edited 04-17-2002).]

CGameProgrammer
04-18-2002, 09:36 AM
I have to ask, why are there no 32-bit z-buffers? I thought it was because of the video memory such a buffer would take up, but since the newer graphics cards offer plenty of video memory, surely it would at least be an option now if that was the only problem.

Do the cards use some sort of optimization for comparison that depends on the size of each entry in the z-buffer? I would have thought a 32-bit comparison would be faster than a 24-bit one, since it's a dword.

j
04-18-2002, 09:41 AM
On nVidia cards, 24-bit Z-Buffer also gives 8 bits of stencil, so it becomes 32-bit aligned.

j

opla
04-18-2002, 10:23 AM
what about that extension ? http://oss.sgi.com/projects/ogl-sample/registry/EXT/wgl_depth_float.txt

According to delphi3D, no card supports it http://www.opengl.org/discussion_boards/ubb/frown.gif

dorbie
04-18-2002, 03:22 PM
CGameProgrammer, are you aware of any video card on the market that has a core design that _actually_ started shipping less than ~3 years ago?

All we have to do is wait and good things will come to us.

My comments about scaling would not apply to a 32 bit float (but would to 32 bit int and maybe fixed point) since any messing around with the value would be bad for precision unless you get better than 32 bit from the vertex transformation. So you'd probably want to interpolate right off the coordinate and store it. A few extra bits in the evaluation of fragment depth becomes desirable. You end up deep in fp arithmetic precision issues which then have a greater effect on fragment z than the representation you choose to store. One principal should probably be modify the data as little as possible after the transform, but you have to consider the fragment evaluation arithmetic precision too.

One thing seems likely, fp 32 bit depth buffers will have limitations elsewhere and those limitations will be virtually impossible to know, without detailed knowledge of the hardware and more smarts than I have.

dorbie
04-18-2002, 03:51 PM
Hmm.... another thought, you probably do want to scale the float, because of the range you aren't going to use all the bits in the exponent, that would buy you extra precision for the fragment evaluation vs what you store.

I wonder if a simple shift of the exponent bits would do it?

[This message has been edited by dorbie (edited 04-18-2002).]

CGameProgrammer
04-18-2002, 06:30 PM
I can't remember the floating-point format, other than that there's a sign bit, exponent bits, and "the rest." But it seems to me that if hardware vendors decided to internally use a 0..1 floating-point buffer, they could use that sign bit for something else, and shorten the exponent part of the variable, using the extra room for the data, the number itself. Right?

j
04-18-2002, 07:12 PM
Well, yes. But getting rid of the exponent and the sign bit so that numbers in the range 0..1 are the only numbers represented leaves you with just the mantissa. So you have a 32 bit value with the minimum being 0 and the maximum being 1. Which is fixed-point, and is pretty much what we have right now, if not exactly.

j

dorbie
04-18-2002, 08:53 PM
Yep, this is getting nowhere fast :-)

The whole point of a floating point as you point out is the exponent.

I can see that you might want to lose a few bits of exponent but goodness, not it all! This is effectively what I suggested with exponent bit shift. The LSBs would be zero but would give better fragment evaluation accuracy due to the larger exponent you start with.

You probably already have IEEE 32 bit floating point from the transformed vertices, so all those old inventive schemes don't buy you anything. The only reason wierd schemes work now is that depth buffers have less precision than the transformed vertex values whether it's eye Z or W you're talking about. When you go from vertex to depth value you started off with more precision, when store as floating point then there is nothing to be gained through manipulation other than trying to preserve as much of the availble precision during fragment evaluation.

CGameProgrammer
04-19-2002, 12:24 PM
Well I never suggested getting rid of the exponent, just shortening it.

Also, dorbie, I was thinking of small fp variables (16 or 24 bits), not 32 bits. I doubt any modifications to the floating-point format will be needed for a 32-bit fp depth buffer, though at that bit depth, fixed point is probably fine.

[This message has been edited by CGameProgrammer (edited 04-19-2002).]

dorbie
04-19-2002, 02:24 PM
Point taken, I wasn't trying to be critical of you.

BTW, on the same train of thought perhaps you want to simply move the exponent/mantissa boundary in the fp representation so that the zero MSB of the exponent becomes the zero LSB of the mantissa for fragment evaluation.


[This message has been edited by dorbie (edited 04-19-2002).]

marcus256
04-23-2002, 10:17 PM
Originally posted by dorbie:
BTW, on the same train of thought perhaps you want to simply move the exponent/mantissa boundary in the fp representation so that the zero MSB of the exponent becomes the zero LSB of the mantissa for fragment evaluation.

Well, this is a no-cost harware operation, and really is only the same as removing the zero MSB (I suppose you're refering to the zero sign bit?), so e.g. you would only use 31 bits out of the 32 bits on a 32 fp representation, since you know the MSB is always zero.

I'm not sure if a 16-bit floating point format would be useful, but a 24-bit floating point format should be able to perform very well:

5 bits exponent + 19 (+1) bits mantissa

Remember, the MSB of the mantissa is always 1, and need not be stored, so you get 20 effective bits of mantissa, and a range equal to a 32-bit fixed point format (the exponent can shift the MSB of the mantissa 31 bits). Numbers in the range:

.111111111111111111110000...

down to

.000000000000000000000000000000010000...

could be represented with this format.