Z Fighting issue with armor pieces

Started by
6 comments, last by frob 9 years, 5 months ago

I Everyone,

I am having an issue with the textures of quads getting mixed up when drawing armor pieces on my characters.

When drawing an Helm on top of a head, in the distance, the texture of the head seems to overlap the texture of the helm.

The quads on each model piece (head and helm) are at different Z, they are not flush, usually a difference of about 0.05f.

Anybody has a tip on how to deal with that issue?

Thanks a lot.

Advertisement

Assuming your units are metres, 5cm should be plenty of clearance.

Could you post the code that generates your projection matrix?

In particular, the first thing I'd want to look at is your near plane - it probably ought to be between 0.2 and 1.0 metres out. A far plane more than about 2000 metres out might be worth pulling in a bit.

You may want to calculate a few instances relating to your problem. Whether or not 0.05 is a sufficient difference depends on several things: z-buffer bitwidth, and the near- and far-plane settings. For example, if your near/far planes are 0.5 / 1000.0, and your z-buffer is 24 bits, at a depth (distance) of 650.0, that's approx. the point where a difference of 0.05 can't be distinguished.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

at the end of the day you have two choices: move the z fighting surfaces farther away from each other, or move the near and far planes closer to each other to increase zbuf resolution. note that the overhead for resetting near and far planes is low. i actually set them to three or four different settings to render a single frame with no z fighting.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Actually, three choices:

The third is that you can just not render the inside of the head (the invisible part) so you don't get this issue where they are overlapping and you don't need to be rendering that part of the head anyway.

A lot of games will break their models down like this, and hide the body where it is under clothing.

Actually, four choices:

Use a logarithmic depth buffer. The depth buffer has good precision close to the near plane, and precision gets worse the farther away things are (by the way, also on floating point depth buffers, due to the way floating point numbers are spaced -- using a float buffer alone won't help).

Other than that, since you're talking of "in the distance", you can address the problem with LOD.

If someone is reasonably far away, you can simply skip drawing the face at all, instead put a small skin-colored blob into the helm's mipmap. Nobody can tell a difference anyway. No overdraw, so no problem, and you save a little bit of ROP, too.

Actually, five choices:

In some cases you may want use polygon_offset in OpenGL or its DX equivalent depth bias(also available in DX9).

Jan F. Scheurer - CEO @ Xe-Development

Sign Up for Xe-Engine™Beta


Use a logarithmic depth buffer.

the directx zbuf IS logarithmic, isn't it?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

the directx zbuf IS logarithmic, isn't it?

It's the same as the OpenGL depth buffer, except for [0,+1] range instead of [-1,+1].

Values are distributed proprotionally to the reciprocal of Z. The ideal distribution would be one whose derivative is proportional to the reciprocal of Z. That's what Kemen's algorithm tries to address (well, it doesn't just try, it actually works...).

So, in one word: no.

A much longer but maybe better writeup can be found here: http://outerra.blogspot.de/2012/11/maximizing-depth-buffer-range-and.html

Yup, there are many different variations on the theme of how to break down your depth buffer.

The classic original z-buffer just stores the distances as a floating point number. If you're familiar with how floats work they are higher precision at low number, lower precision at far numbers. Since they just subdivide the near and far plane it gives a very unequal distribution.

You've got traditional z buffer algorithm, then algorithms like w-buffer, logarithmic z, inverse z, irregular z, s-buffer, hierarchical z, and many more methods available to compute your depth buffer value. You can even have depth buffer values based on compute shader results.

There are a huge number of functions you can use, all that matters is that the result can be run through the graphics card's depth test function to give a clear less/equal/greater comparison.

This topic is closed to new replies.

Advertisement