Near and Far clipping ratios

I know it is advisable to keep the near and far clipping planes’ ratio low. But what is the recommended ratio? I’ve heard the near plane should be 1.0 but this leads to an inability to get very close to objects, but then you could overcome this apparant inability to get close to objects by drawing them much larger, however, then you have the problem that you’re more limited to the distance of objects. For example, I’m drawing a planet, and I want to be able to fly VERY close to the surface of the planet. But to achieve this appearance with the near plane set to 1.0, I have to make the planet HUGE (in terms of its radius)! Otherwise, I hardly get close to the planet at all and BAM I’m inside the planet. I realize the ratio can be larger with a larger Z-buffer (32bit). But is current hardware well equiped to use a 32bit Z-buffer? Or is it best to stick with 16bit? And, taking all of this into consideration, what is the best way to simulate things like space and drawing HUGE objects like planets and EXREMELY distant objects like stars? Are there any tricks anyone has they’d like to share?

I remember a long time ago (in a galaxy far, far away) there was a title called Microsoft Space Simulator. It was monster cool because you could pump the time compression way up and fly at near-light speeds through the galaxy. You could start somewhere within the solar system and you’d see the actual stars in their real places. And then you could accelerate and you’d see the planets of the solar system whiz past and become little dots in the distance and eventually, you’d begin to see the stars that make up familiar constelations start to move and then you could eventually fly around them and see how they didn’t lay on a flat plane as they appear from our solar system. This kind of LARGE_SCALE universe is what I’m seeking to create and I’m just wondering if anyone has any tricks to rendering DISTANT objects and still maintain accurate depthbuffering.

2 options
measure the zvalues of everything in your scene everyframe and set the near/far values to those every frame.
or use 2 depth ranges ie draw all the near stuff change the near/far planes and draw all the far stuff.
ive done it this way with a space thing and IIRC there was no zfighting from 1m to a billion kilometers

So you did it using the second method you mentioned? Cool! Thanks, man! Could you elaborate a bit on how you actually implemented that system? How do you actually use two different depth systems and how do you handle the rendering of something like that? I’ve heard if you use a near clipping of less than 1.0 you’ll run into problems. But are you saying this is not the case? Thanks again!

I can’t understand how you’re generalizing the zbuffer problem.
It’s always cool to have the distance between the planes as small as possible, but the scale of the displayed object should specify the ideal ration (would be limes to zero… ). So, get the maximum z value of any object (you can use bounding spheres) and the minimum z value, and use them. It should always give the best results.

Whoops, I think I oversaw some details in your question. Sorry.
Maybe, you don’t really let the far-away object get far away, but do a lod with scaling the object down appropriately.

Originally posted by Michael Steinberg:
Whoops, I think I oversaw some details in your question. Sorry.
Maybe, you don’t really let the far-away object get far away, but do a lod with scaling the object down appropriately.

That sort of technique might work for some things, but for other things, you’d lose the whole feature of depth buffering: occlusion. Do you have any ideas as to how to implement this other guy’s suggestion? It sounds pretty good especially seing as how he says he’s already implemented it with success. Although, depth-sorting everything before rendering is something I havn’t had to deal with yet.

Punchey,

You don’t have to depth sort everything, its more of a case of picking a distance and having objects as being either in front of or behind that imaginary ‘line’.

In its simplest form, you just test each object as you go to draw it and put objects on the near side of the imaginary line aside for the next pass with the ‘closer’ far and near clipping planes.

When you do the second pass, just clear the Z-Buffer (but not the frame buffer obviously) before you draw.

I guess that if your distance is very large, you could use several of these ‘clipping bands’

I haven’t actually done it yet, but plan to soon. I’m sure there are a few things I haven’t covered like what to do with objects that straddle the boundry and such,and I’m sure there are more efficient implementations than my simple explaination.

well, you’d have to do more than just clear the Z-buffer. You’d have to reset the near and far clipping planes because you’d still get depth fighting. The problem I’m running into is if I draw using a near clip of 1.0, it looks as though I can never get close to anything like a planet or such. If I make the planet large enough to look good so that I can get what looks to be reasonably close to it without it dissapearing, then when I fly away from the planet, it dissapears beyond the far clipping plane FAR too early. So I’m at a loss of what to do. Is it much of a performance penalty to reset your near and far clipping planes each frame? And if not, which calls are best to use to accomplish this? Also, I’m noticing that whether I use a 16bit or 32bit Z-buffer, it still has the same ammount of depth fighting.

I think it’s almost necessary to reset the clipping planes every frame, just to improve visuals. For my own purposes it seems to be far easier though than to yours…
Maybe replace the galaxies with a simple billboard when you are far enough away. They won’t get depth fighting then. You could even project them on a sphere or something else. It’s just that you can’t see a whole galaxy detailed from one point. AND maybe it is more easily to apply your own depth sorting, only drawing them over each other. I mean, planet’s don’t intersect, so you can sort them and do a far to near rendering without depth test. That would be the way, I think.
And planets are almost always convex.

[This message has been edited by Michael Steinberg (edited 12-05-2000).]

About the 32-bit Z-buffer thing, do you know if there’s a big performance premium on today’s hardware for using one as opposed to a 16-bit Z-buffer? I’m beginning to think I’m going to need a whole message board dedicated to the topic of Space combat sims. The reason being that after getting into it and trying to implement things like laser beams and stuff I just have a TON of questions to ask. If anyone else out there is doing something like this themselves, it wouldn’t hurt for us to collaborate together and brainstorm to come up with some solutions to these very basic problems.

Might be that it didn’t get clear, but I’m also (trying) to write a space combat sim. Maybe we should work together or at least change ideas…

I almost forgot, since a planet or something could lay on the border between the two sets of near/far clipping planes, I suppose you’d need to make them overlap a bit? And I further suppose that the size of this overlap would essentially define the maximum size of an object in your universe that could possibly cross that border? Is my reasoning correct here or is there a way to get around this?

I don’t think that it is quite a good idea to use multiple sets of planes.
You’d still have to render back to front in a way, and you’d have to clear the depth buffer many times a frame.
Here is what I would do:

-1. ( ) Define a maximum distance where normals objects would be visible
0. Define a real greate ratio, the near planes lies, where the maximum distance is

  1. Turn off Depth testing
  2. Sort Planets after depths
  3. Draw planets back to front
  4. Set the actual ratio for near objects
    4.5. Switch on depth testing
  5. Draw planets that lied on the max-distance-plane a second time or in front of it.
  6. Draw all your great space ships

So you are basically saying to draw distant objects scaled down but actually near with depth testing turned off, and then turn depth testing back on and draw near object actual size?

Nope, for far away planets, only switch off depth tests, to not let the ratio get great. I hope you can follow me.

You’ll have a great ratio for undetailed far-away (convex) meshes, but you won’t do the depth test on it, to have the full precision of the zbuffer completely for the close objects that are more complex in rendering in the correct depth order.

So you’re talking about the accuracy ratio of the depth buffer once used. I thought the ratio of the depth buffer was determined by the near and far clipping planes. If you set a near of .5 and a far of 10000 you’ve defined the ratio of the depth buffer. AFAIK using the depth buffer is not what determines the resulting ratio of accuracy. In other words, it’s not as if I could set up a near of .5 and a far of 10000 and then just do all my depth-tested drawing between .5 and 100 and expect that to keep the ratio down because the depth buffer’s accuracy was determined when I set the near and far clipping planes. Or am I wrong about this? If I’m right, then to fix the depth accuracy problem you’d have to define a smaller depth range such as 1.0 and 5000 but, unfortunately, then whether I disable depth testing or not, objects farther away than 5000 will get clipped.

“well, you’d have to do more than just clear the Z-buffer. You’d have to reset the near and far clipping planes”

I sorta took that as a given Does anyone know what the penalty for changing the clipping planes are? In my situation I only need probably 2 or at most 3 of the clipping bands I described anyway.

I have seen this technique in a commercial engine using 4 clipping bands (thats were I got the term from ), and it works well without noticable FPS drops. That was performing all transformations in the engine itself, so maybe the penalty is greater for OpenGL and/or HW T&L, I’m not sure. I guess I’ll find out soon…

I’ve heard of tricks that eliminate the need to actually clear the Z-Buffer,so maybe that helps the Z-Buffer clear penalty.

About the 32bit Z-Buffer, alot of cards force the Z-Buffer to 16 bit when you use 16 bit colour depth, you probably thought of that, but just in case.

So if I gather what you are saying Michael, then you are setting up the rear clipping plane to a far distance, turning off Z test and write, and using the painters algo to draw the distant planets.

Then, change the front and rear clipping planes to a desired value, turn Z test and write back on and draw the remaining planets and objects.

Actually thats not a bad idea considering all the planets are spheres, and the other objects should be too small to be drawn.

Originally posted by BK:
I’ve heard of tricks that eliminate the need to actually clear the Z-Buffer,so maybe that helps the Z-Buffer clear penalty.

But using that trick, you have to leave the near and far clipping planes on the same value for each frame. I’m not sure, if this trick is used in current graphic-card drivers.

I think I’ve not been clear while the last explanations.
AFAIK, anything before the front or behind the back planes won’t be rendered anyway.
If you have a great ratio, you’ll get depth fighting in detailed object, which are NOT CONVEX. Planets ARE CONVEX. For CONVEX bodies, planets, you don’t need any depth testing in this case, since they won’t intersect. SO:

1: Sort the planets after their distance from the viewer.
2: Specify a maximum distance where detailed objects like space ships, which are in fact very small can be seen. You could fade them out with black fog if you want to.
3: Set up the far an the near planes: The near plane gets the maximum distance of point 1.
4: Clear Depth buffer
5: Disable depth buffer
6: Draw any planets that are far away with back->front ordering, so you won’t need depth testing.
7: Setup the planes: Near plane: as near as any object can get, Far Plane: The maximum distance from point 1
8: ENABLE depth test
9: Draw your highly detailed objects like starships.

Hope I’m clear now.
BTW: My lost teeth don’t hurt…Funny.