Thread: z-buffer accuracy

  1. #1
    Registered User
    Join Date
    Jan 2002
    Posts
    75

    z-buffer accuracy

    i've begun reading the opengl programming guide and came to a point where the book mentioned that values closer to the near clipping plane have greater depth accuracy than those nearer the far clipping plane (with perpspective projections). the reasoning behind this was because during the perspective divide the z values were scaled non-linearly. i looked online a little further into the subject, and what i figured is that the z-values are scaled in such a way because that's the only matrix transformation that will produce the desired change of the perspective canonical view volume to parallel canonical view volume (i don't know any linear algebra except how to multiply matrices so i might be wrong). my question is then, why must we HAVE to use a matrix tranformation. why can't we just alter the x, y (w?) values and leave the z value unaltered?

  2. #2
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    I'm not sure I understand your question. But we have to alter the Z value when rotating an object. Suppose you had a cube, and rotated it over the Y axis until what had been the back was the front. The z values obviously would have to be transformed. If they weren't, everything would be all messed up.

    I also don't know why the Z-buffer would lose accuracy with distance... I thought it was storing a Z-coordinate for each pixel of the screen. That would only become a problem when you got to the point where one pixel is covering several z-coordinates.
    Away.

  3. #3
    Registered User
    Join Date
    Jan 2002
    Posts
    75
    i'm referring only to projection.

    edit: if the zbuffer doesn't have enough bits per pixel and the distance between the near and far planes is relatively large then zvals far away from the viewpoint but close to each other (after transformation) might map to the same depth value in the zbuffer, leading to anomlies. this is because the new zvalue is z' = a - b/z (a,b >0). as you can see, for values further away, the diff between b/z is small, where as for closer vals it's large.
    Last edited by genghis; 08-09-2003 at 01:09 AM.

  4. #4
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    To answer your question I have no clue why we must use matrix multiplication to perform these various projections. It's just how things are done behind the scenes and there's no way to change it.

    I do think matrices suck for programming, because putting equations into their equivalent matrix form generally takes more calculations, and more calculations means slower frame rendering and more inaccuracies in floating points.

    take these two functions which are mathematically equivalent (if you don't believe me use your ti 83) and pass in 9.81...they should both yield 32, but the first actually returns 30

    bad:
    Code:
    inline	float	METERTOFEET(float	meter)
    {
    	meter*=(((8+(1/3))*(1/2.54))); //works but too inaccurate
    }
    good!
    Code:
    inline	float	METERTOFEET(float	meter)
    {		
    	meter*=100; 
    	meter/=2.54; 
    	meter/=12; 
    	return meter;
    }

  5. #5
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    Why not just multiply meters by 3.280839895 Silvercord? That will work just fine...
    Away.

  6. #6
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Thats much less accurate than doing those steps, because of precision. It's more precise to have the PC calculate 1250/381 than to enter 3.280839895.

    Code:
    #include <iostream>
    
    using namespace std;
    
    int main( void ) 
    {
      
      if( 3.280839895 == ( 1250.0/381.0 ) ) cout<<"Huzzah"<<endl;
      return 0;
      
    }
    This outputs nothing.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  7. #7
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    it all illustrates the same point. I did the second way the way I did because it's easier for me to read, even though if you want to be super technical it's less efficient because of the added calculations

    I was proving that matrices are bad because the added calculations introduce error, and in rendering terms z fighting!
    Last edited by Silvercord; 08-09-2003 at 10:34 AM.

  8. #8
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    XSquared - Try casting both of those values into a float and outputting the values. Silvercord was returning a float from his function. Floats are only accurate for seven decimal places, and after that, it's gibberish. The values should be the same for at least the first seven decimal points, and you don't need more than that anyway
    Away.

  9. #9
    Registered User
    Join Date
    Jan 2002
    Posts
    75
    to say that a matrix is a bad calculator might be a little off. matrix multiplication is very general (allowing for all sorts of transformations on points) and because of its nature, it is ideal for hardware implementation since most of the computing can be done in parallel. trying to implement very specific transformations in hardware would be much more tedious and expensive (and you probably wouldn't gain much out of it). so matrix multiplication is a good thing for computer graphics.s following this reasoning, maybe the matrix transformation used for perspective projection is simply because it would make things unneccarily complicated to provide for specific projections in hardware. still, i'm rather dubious. i think the chosen transformation has more to do with preserving lines, planes, and what not.

  10. #10
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    I think what he is talking about is using W-Buffer's instead of Z-Buffers. W-Buffers give you more accuracy towards the far plane by storing 1/z (w) instead of z. W-Buffers are deprecated and rarely supported in hardware. Stick to your Z-Buffers.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  11. #11
    *******argv[] - hu? darksaidin's Avatar
    Join Date
    Jul 2003
    Posts
    314
    Depth buffer precision is affected by the values specified for zNear and zFar. The greater the ratio of zFar to zNear is, the less effective the depth buffer will be at distinguishing between surfaces that are near each other. If
    r = zFar / zNear

    roughly log2r bits of depth buffer precision are lost. Because r approaches infinity as zNear approaches 0, zNear must never be set to 0.

    from here.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  2. writing a pack-style function, any advices?
    By isaac_s in forum C Programming
    Replies: 10
    Last Post: 07-08-2006, 08:09 PM
  3. buffer contents swapping
    By daluu in forum C++ Programming
    Replies: 7
    Last Post: 10-14-2004, 02:34 PM
  4. Tetris Questions
    By KneeGrow in forum Game Programming
    Replies: 19
    Last Post: 10-28-2003, 11:12 PM
  5. Console Screen Buffer
    By GaPe in forum Windows Programming
    Replies: 0
    Last Post: 02-06-2003, 05:15 AM