I’m using gluperspective for a program (solar sys type thing), and the program draws objects that are behind other objects.
What commands determine whether something is drawn or not?
With gluperspective, you shift the system, while when I used glortho, objects were drawn correctly, not overdrawing each other.
More specifically, when an object moves about the center of the system, the system rotates with it so that you “ride” the planet so to speak. Since the arctangent function returns a number between pi/2 and
-pi/2, at pi/2 increasing, the vector orthogonalizes and rather than follow earth around, you’re on the exact opposite side of the sun…that’s fixable, however, when I use gldepthfunc gl_greater, then as you follow earth (assuming it’s on the interval where it follows it correctly), the moon always ends up hidden when it passes, when I use gl_less it always end up showing, even when it’s in behind the earth with respect to the viewport.
Does that mean I have to constantly toggle between the depthfunc constants? That doesn’t make sense since to do that I could just create a drawing order.
All help appreciated.
[This message has been edited by Kurt B (edited 05-23-2000).]
Whoops…meant to edit and wound up reposting the message…sorry
[This message has been edited by Kurt B (edited 05-23-2000).]
Hmmm … yuo must have done some mistake in your code, you should really not need to switch depth function anytime.
how you setup gluPerspective?
you should NOT specify a hiter (near clipping plane) equal to 0: 1e-1 is a good value, instead.
Okay…I did have the near plane set to 0.
I changed it to .000001 or something.Thanks
However, I was beginning to think the problem was elsewhere and began rewriting it…
I setup the program so that the motion was in the xy plane. Objects in general move about the xyplane. Now, if the depthfunc is only looking at the z coordinates of the objects, it would find them all to be zero. I was thinking THAT was the problem. Even though the view is zoomed into the planets and it follows them in perspective, the depthfunc doesn’t know that with respect to the viewer, objects that are closer, say in X should be overdrawing others. I guess depthfunc would have to determine where the viewport is, what’s going on there, and decide closeness–which I doubt it would do.
Anyway, I’m rewriting the program to work in XZ and make the Y axis the vertical Axis.
Thanks for the help. I’ll see what happens.
Would like to say a few words about near clipping plane.
The documentation in MSCV6 says that you lose log2(far/near) bits of depthbufferprecision. This means that if you set far to, say 1000, and near to 0.000001, you will lose loads of bits in precision. If you set near to 0.1, you will gain more bits in precision, but I can guarantee you will not notice any difference (if you have your far plane at 100 or more). I usually use a near:far ratio of 1:10000.
Why do i lose log2(far/near) bits of depth precision? I had far=6000 and near=1 and noticed some z aliasing with 16 bit depth buffer, but setting near=10 helped alot.
Can someone explain why this happens? Doesn’t the depthbuffer store just the depthvalue linearly between near and far?
No, Z-buffer values behave like floating-point numbers, so most of their range is concentrated toward the near clipping plane.
I thought that was a W-buffer. What is then a w-buffer?
W-buffer has even world-space distribution of depth values. There is the same precision no matter how far away an object is…
And that “losing depth precision” thing :
It’s the ratio of near/far that matters… the bigger near is, the more concentrated depth values near you are spread out (is that comprehensible?)
So, from what i understand the W-buffer is a linear representation and the Z-buffer is a floating point representation of the depth value? I thought it was reverse, in Glide (well, i used to program in Glide before) when i used z-buffering i got a linear depth buffer, but the W buffer was floating point …
Am I missing something?
Well, the book “Real Time Rendering” says that Z buffer has “non-uniform” distribution, and that “the resolution is finer at the lower depth values.” It then goes on to say, in essence, set your near as far out as you can On the next page, about W-buffering : “Here the precision of the depth value is always uniform for all depths.”
But W-buffering isn’t a feature of OpenGL, it’s usually assumed to be a Z buffer. AFAIK there’s no way to detect which one you have.
Hmmm … strange, I’m very very sure about what was Z buffering and W buffering in Glide (because i actually picked out the 16bit floating point depth buffer value and manually made it into a 32 bit float and compared to other depthvalues to check for visibility). But, well, what’s Z or W doesn’t matter much as long as OpenGL uses the better method.
First a minor add to my previous note. I recomended a near:far ratio of 1:10000, but Humus said he noticed aliasing at a ratio of 1:6000. Shold have said that I was using 32-bit z-buffer. If you are using 16-bit buffer, of course, you should have smaller (?) ratio.
Now, think I have a theory WHY the z-buffer is non-linear. It’s because the way a float is built up. A float is built up with x bits of “number” (hmm, forgot what they called it), one signbit and y bits of exponent. A float of 100 is stored (on bitlevel) as 1*10^3 or similar. Now, imagine that the “number” part exceeds one. This will cause the exponent to increase, and let the “number” part be divided by 10. Now each bit in the “number” part will give ten times as mush to the final value because the exponent is increased by one. This is what causes the non-linearity. At a lower exponent (near the near plane), each numberbit has a higher precision. Near the far plane, each numberbit adds a greater value to the final value (“bigger steps” between each value).
w-buffers are linear because it’s using integers to store depthvalue. Integers are using all bits to store the number, and no exponents. This means all bits will always add the same amount to the final value.
Just my own theory. If anyone knows this is wrong, say so, and if you know how it really is (if it’s wrong), tell me
[This message has been edited by Bob (edited 05-25-2000).]
Your theory is correct. Some details however:
There’s no signbit here, and 110^3 = 1000 … and it’s no 10-exponent, it’s 2- exponent, 100 = 1.56252^6.
I do fully understand how this work, the problem is that i thought OpenGL used the linear model, but it doesn’t (and that good). And for some reason W and Z has different meanings in OpenGL and Glide.
First, sure, 10^3 sure is 1000, but I typoed (believe me or not, but i did ).
Second, OK, maybe it’s a 2-exponent. I thought it was a 10, but now i know.
Third, there’s no signbit?
Actually, the aformentioned book explains it, and the reason is because of the shape of the frustum. When you have an orthographic projection, a Z buffer IS a W buffer. The more like a pyramid it’s shaped, the more the Z buffer’s values are crowded up near the beggining. The reason this occurs is because of the shape of the frustum… Without quoting 2 pages from the book it’s not that easy to explain, but I hope this helps
What you should do to acheive best results is set your near as far out as possible, and your far as close in as possible, thus wasting the least amount of precision…
BTW, I HIGHLY reccomend this book. (Real Time Rendering) It’s bascially a discusion of different algorithms and techniques… Very nice It is NOT a book about OpenGL, but it is very helpful when you want to understand stuff (like this)
Well Kaeto … i do understand how i works, it’s only a problem on what is Z and what is W. Your book tell me that this floating point stuff is Z and W is linear. But the Glide SDK docs tell me that W is the floating point representation and Z is the linear one. From my point of view i must say that it’s more logical to call the linear representation “Z” because you have your Z axis linearly into the screen.
It’s a 2-exponent since were talking binary numbers here … if you think about it a while you’ll find that a 10 exponenet would not be very good (loose precision, harder to implement, dubble representations of the same number … etc)
And you have no signbit since you do not need one, 'cause you only have either positive or negative depthvalues at the pixels visible on screen. In Glide you would get a 4 bit exponent and 12 bit mantissa if you used what they call a W-buffer.
I am 100% certain that the glide SDK is wrong. I can’t count how many times/places I’ve heard that description of Z/W And I’m pretty sure that the numbers are integers in both, at least on most accelerators. I can post the whole 2 page thing, or email it to you if you want… it’s a bit more in-depth…
I accept that the Glide SDK might be wrong about W/Z, but I think that which letter you use is not the most important issue.
However, when you have a non-linear representation it isn’t integer numbers, and I’m completely sure about that since I did pick out the 16bit numbers from the depthbuffer and manually converted it into a normal 32bit float, the Glide SDK was very detailed about how it was physically stored, as I said in earlier post, 12bit mantissa and 4bit exponent … at least at 3dfx hardware, but i think it shouldn’t differ too much from other vendors implementation. Using integers for a non-linear representation wouldn’t be a good solution.