Distant objects, 2 passes, 2 far planes, clearing zbuf, zbuf depth

Started by
12 comments, last by Norman Barrows 10 years, 11 months ago

been thinking about drawing distant objects, zbuf depth, z fighting, far clip plane values, etc.

in one of my projects, i've gone to 24 bit zbuf and far plane of 1000 to draw distant clouds with no z fighting in the scene.

but i'd like to do things with 16 bit zbuf if possible, for maximum compatibility.

I'm targeting baseline PC's for maximum compatibility.

i'd do 32 bit zbuf, but my test rig doesn't support it at high resolution (on board graphics chip only).

so i guess the first question is, should i worry about supporting 16bit zbuf, or can i design around a guaranteed minimum of 24 bit being available?

if i should worry about 16 bit, then i was thinking of trying a 2 pass approach:

1. use 16 bit zbuf for compatibility
2. set far plane to high value (say 10,000)
3. draw distant stuff
4. set far plane to low value (300 or so)
5. clear zbuf
6. draw close stuff

thoughts? suggestions? anyone tried this?

it does cost an extra 2 set_projection_matrix calls, and one extra clear_zbuf call over the normal single pass with non-changing projection matrix.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement

We're using 2 pass in many of our projects (mobile devices). It works fine. But you will lose some benefit from hw provided hidden surface removal function, and also other function depending on z buffer (texture). For the far-pass, we have less polygon and light pshader than near pass, and almost of things in far-pass are solid. And we didn't clear zbuffer before the 2nd pass, just set the depth range.

Before you try something that drastic, try experimenting with your near plane. The far plane has very little impact on z-fighting (counter-intuitively, sometimes increasing the far plane can help resolve z-fighting issues!), whereas the near plane has a huge impact.

This is because the hardware depth buffer is hyperbolic. As a very rough rule of thumb, imagine half of your precision going towards representing the objects between near and 2*near, and the other half representing objects from 2*near to far.

[edit]You can use this form to see when 24 depth buffers were introduced:

http://zp.amsnet.pl/cdragan/query.php?dxversion=9&feature=formats&featuregroup=selected&adaptergroup=groups&adapterselected%5B%5D=ATi&adapterselected%5B%5D=Intel&adapterselected%5B%5D=NVidia&featureselected%5B%5D=39&featureselected%5B%5D=41&featureselected%5B%5D=42&featureselected%5B%5D=44&featureselected%5B%5D=46&resource=SURFACE&usage=DEPTHSTENCIL&orientation=horizontal

Looks like you'll be fine, except for ancient Intel cards. If you're going to support these, I'd recommend getting one off ebay for a few bucks so you can test the framerate on it too wink.png

[edit2] That list is for the automatic depth buffer that you get with your device.

If you want to create extra depth buffers, or depth buffers that can be read as textures, then support is very spotty until DX10-era cards. e.g. there's some cards that support an automatic 24-bit depth buffer, but only 16-bit depth buffers if you want to be able to bind them as a texture.

And we didn't clear zbuffer before the 2nd pass, just set the depth range.

clever. guess you had the depth to spare.

in the title i mentioned, a 16 bit zbuf is only good out to a range of about 300 or so, given the meshes being drawn, and how close their faces can be in Z. 16 bit zbuf and 1000 far plane causes some z fighting starting at about 250 range.

in another title i'm working on, a flight simulator, visible range is 10000 d3d units at 100 feet per d3d unit (189.39 miles). and the largest target (an airship) is visible out to 8000 d3d units (151.51 miles).

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

This is because the hardware depth buffer is hyperbolic. As a very rough rule of thumb, imagine half of your precision going towards representing the objects between near and 2*near, and the other half representing objects from 2*near to far.

non-Linear?! well that explains a lot!

ok, i have the near plane at 0.1 d3d unit. in that title, the scale is 1 foot = 1 d3d unit. .0.1 is required to fit the player inside a small lean-to or shelter (pup-tent sized).

so, well i was going to say i should use a 0.1 near plane only for location=INSHELTER, but you can still see the world, and z fighting at 250 range and 16 bit zbuf...

since shelters are a world object, i can't create a "bigger" scene or model that a bigger near plane will fit in. think of a model of a pup-tent, with one end open. now put the camera inside the pup tent in the center, about 1 foot off the ground. the tent is about 3 feet tall. its pretty tight in there. but a nice effect, like you're stretched out on your sleeping bag, gazing out at the world.

i did notice that z fighting got a little worse when i moved the near plane from 1 to 0.1 to squeeze it inside a shelter.

also i do recall something about using as far a near plane as possible, during my last round of directx optimization research.

sounds like i can rely on 24bit being available, and i can do two (or more) passes if needed.

what about setting the near plane of the 1st pass to the far plane of the second, or a little inside it:

pass 1: near=450 far=10000

pass 2: near = 0.1 or 1, far = 500

that would keep the zbuf resolution of pass 1 higher than near=1 far=10000.

that way you could "stack up" zbufs one behind the other, draw out to any range with multiple passes, and still get a high resolution zbuf for each pass.

i think that may be the answer.

fortunately, it looks like i can count on a 24bit zbuf being available for the primary swap chain, so hopefully I won't have to go to a 2 pass method.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

And we didn't clear zbuffer before the 2nd pass, just set the depth range.

clever. guess you had the depth to spare.

in the title i mentioned, a 16 bit zbuf is only good out to a range of about 300 or so, given the meshes being drawn, and how close their faces can be in Z. 16 bit zbuf and 1000 far plane causes some z fighting starting at about 250 range.

in another title i'm working on, a flight simulator, visible range is 10000 d3d units at 100 feet per d3d unit (189.39 miles). and the largest target (an airship) is visible out to 8000 d3d units (151.51 miles).

Plz check this page, http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html

near value is more important than far value.

1. use 16 bit zbuf for compatibility
2. set far plane to high value (say 10,000)
3. draw distant stuff
4. set far plane to low value (300 or so)
5. clear zbuf
6. draw close stuff

Personally I wouldn't touch 16bit z with a ten-foot pole. Standard is 24bit+8bit stencil. Even 1st gen Atom systems support it as far as I recall and I'd advice you to not even try using anything lower in perf.

By the way, I I experimented the "double frusta" method you mention, albeit I couldn't look it in depth for example the performance implication with shadows and such.

In short: it works... sort of. But I couldn't manage to fix a few missing pixels on the "zMiddle" plane. In certain cases, those were quite noticeable.

Previously "Krohm"

i implemented a Zset_clip_planes(near,far) routine.

now i set the clip planes to 400 and 2000, and draw clouds. then i set the clip planes to 0.1 and 1000, and draw everything else.

works great.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Nice to know. No missing pixels?

Previously "Krohm"

Nice to know. No missing pixels?

By the way how many times can you do this trick? I mean, does it work for really large distances or do you eventually lose all precision for very high near and far values (say you were rendering very distant objects). Or do you use a different method for this?

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement