Archived

This topic is now archived and is closed to further replies.

Z buffer accurate up close, but not far away.

This topic is 5088 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am currently writing a GUI for my sprite engine. To make things really easy, I am going to simply adjust the Z distance of windows when they are clicked on. That is, if a window is clicked on, it is moved closest to the camera and all of the others are moved back. So the user doesn''t see a difference, the changes in position are small (everything is viewed at 100 units away, and the changest are probably going to be 1/100 of a unit or less. I could draw from back to front, but for speed purposes I am first going to draw the buttons then the text. Therefore, I need the Z-buffer to do its magic. The problem is that at regular distances, this small difference in distance isn''t enough and the Z buffer isn''t working right. If I get really close to my buttons, the z buffer works just fine, but as I move further back, it seems as if the small differences aren''t large enough and some of my windows are in front when they should be in back. Is my only solution to switch textures for every button (text and the button graphics are in different textures) or is there a way to increase the sensitivity of the z buffer so that the buttons are drawn correctly at further distances. --Vic--

Share this post


Link to post
Share on other sites
My understanding this is a hardware limitation.. ZBuffer are only 16 or 32bit buffers and you tend to mix your buffer with another type of Buffer like a Stencil buffer so it becomes a 15/1bit buffer. This means with small and mintue distance changes the precision of the ZBuffer just isn''t up to the task.

This is all quoted out of memory, so while I think the gist of what I''m saying is correct some small parts may be inaccurate..

Share this post


Link to post
Share on other sites
In your perspective matrix, what is the z-value of the far plane? (If you''re using D3DXMatrixPerspectiveFovLH it would be the last param). You may want to try and make that value smaller than it currently is. Also, if it is 0 or null, you will have problems.

Share this post


Link to post
Share on other sites
I''m not entirely certain, but couldn''t you just load an orthographic matrix and make the differences in your z coordinates an arbitrary size? This seems to be the effect you''re trying to emulate anyway...

______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
CircleSoft: I have to keep my far plane high because I am also rendering stuff that is far away. That is, my GUI will be used as a menu in all types of games; and some games have objects that are very far away.

The near plane is about as large as it ca be before I start having problems with it.

Thunder Hawk: I don''t want to use an ortho view because I take advantage of the size differences in my games. In my engine I set the view, draw all game objects then jump directly to the GUI. If I were to use a Z Buffer, that currently wouldn''t be a problem because I sort my sprites from back to front and don''t use Z for alpha reasons on them.

I have decided that I will just make two versions of my GUI. A layered version and a fast version. The layered version will draw each button in its entirety before moving on to the rest. This will be slow, but allow for windows on top of other windows. The other version will assume that there is only one layer and it is up to the programmer to make sure that buttons don''t overlap. Here I will draw buttons in components to minimize texture changes.

Hoever, thanks for your help all. Always good to learn something new.

--Vic--

Share this post


Link to post
Share on other sites
You realize you can use an ortho matrix for your GUI and a normal matrix for everything else, right?

______________________________________________________________
The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ
MySite
______________________________________________________________

Share this post


Link to post
Share on other sites


I remember reading in an Andre LaMothe book that Z-buffers are inaccurate at large distances, but W-buffers are not.

I''ve never used a W-buffer so I can''t tell you much beyond that.

Oh, and the book was about the DirectX8 era, so it should be relatively current.

~Sparticus

Share this post


Link to post
Share on other sites
The error at large distances can probably be attributed to floating point quantization. Smaller numbers can be more accurately represented than large numbers. As far as rendering your UI elements - unless you''re doing some kind of parralax scrolling that needs perspective transformations, I would tend to agree with the other posters about switching to a second UI-specific matrix.

Share this post


Link to post
Share on other sites
If you have a 24-bit Z buffer, and reasonable near plane distance, then you shouldn''t really be seeing problems.

Z buffers have linear resolution in framebuffer space. That means that, if you count the DEPTH of a pixel as well as the width, a pixel in the framebuffer that''s near the plane may be 1 cm x 1 cm of screen real estate, and 2 cm of depth (for example). That same pixel, if it''s representing something far away, might be 1 m x 1 m, and then it would represent 2 m of depth interval.

W buffers represent the same distance of depth no matter what the pixel represents. Thus, if the pixel is up close, it''ll have 30 cm resolution. If it''s really far away, you''ll still have 30 cm resolution. The problem with this is that you lose WAY too much precision up close, and you get precision way far out that you don''t need. Z is much better, because it scales just like pixel size with distance.

Share this post


Link to post
Share on other sites
What would actually happen if someone used three matrices, one with a relatively close near plane for objects that are extremely close, another with a more modest near plane for 90% of the geometry and then a third matrix with its planes extremely far away for rendering objects in the distant background with better precision. So long as all the matrices share the same FOVs would this technique work seemlessly or would there be some serious noticable flaws?

"I find it immoral to have a battle of wits with an unarmed man"
~Vendayan


[edited by - Vendayan on January 8, 2004 1:57:55 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Vendayan
What would actually happen if someone used three matrices, one with a relatively close near plane for objects that are extremely close, another with a more modest near plane for 90% of the geometry and then a third matrix with its planes extremely far away for rendering objects in the distant background with better precision. So long as all the matrices share the same FOVs would this technique work seemlessly or would there be some serious noticable flaws?


As long as you clear your Z-Buffer between passes it will work. However, you need to draw the far things first, which can reduce the benefits of doing so. For example, if you used a 2 pass approach (1 for the world, 1 for the GUI) and draw the GUI last, then many things that would have been occluded by the GUI will be rendered anyway in the first pass. Visually it will be fine, but it is a performance hit.


Stay Casual,

Ken
Drunken Hyena

Share this post


Link to post
Share on other sites
Hmm... I see, that is a bit of a performance hit having to refill the entire scene potentially for scenes that are densely occluded

Yet is this still how many games accomplish this?

"I find it immoral to have a battle of wits with an unarmed man"
~Vendayan

Share this post


Link to post
Share on other sites
First things that come to mind, some of these have already been mentioned:

Use a W-Buffer instead of a Z-Buffer.

Change your clipping planes-if you are rendering other objects behind your windows, render them first, then reset your z-buffer with your clipping planes.

Use ZBias - Research SetRenderState & D3DRENDERSTATE_ZBIAS


-----------
VenDrake

"My stupid jar is full. I can''''t talk to you anymore."

Share this post


Link to post
Share on other sites
NOTE: I''ve never tried this so I don''t know how well it will work. It just occurred to me.

-Clear your scene
-With Z enabled, turn off your colour channels
-Render your windows quickly (no text, no detail, just base shape), this primes your Z-Buffer
-Turn colour channels back on
-Render your scene, Z-Buffer will still reject anything that would be occluded
-Clear Z
-Set clipping planes to give disgusting precision only up to 100 units (the farthest your UI is rendered)
-Render GUI

Still not ideal, but should help some of the performance issues and give you extreme precision for your GUI.

Though if your GUI blocks large segments of your scene, you may want to do some sort of occlusion culling which would speed things up even more and require less fiddling.


Stay Casual,

Ken
Drunken Hyena

Share this post


Link to post
Share on other sites