Game Development Community

Z-Fighting when more than 1000 units from origin

by Devin Passage · in Torque 3D Professional · 09/21/2010 (3:09 pm) · 5 replies

Z-Fighting begins about 1000 units in any direction from origin and gets worse the farther you get away. By 10km there is visible flickering on everything, by 100km it is unwatchable.

you can see this by just loading up empty room, and making a Station 1 model at like 100000 100000 10, and viewing it. The best way to get to where you can see it is just move it and then select move camera to selection.

as can be expected, the z fighting consumes most of the model. while most games do not need to go this far into the world, open world, flight sims and space sims do.

One possible problem is that F32s lose their decimals at numbers this large, which may be creating the z-fighting in the first place. Changing all of the matrices to F64 would take longer than just a casual fix.

Another option is just to catch very large numbers before they get sent to rendering, but I am seeing numbers I don't understand in the debugger, such as an objectToWorld that is dramatically different than the corresponding object's worldToCamera.

Anybody with some skill in how the graphics work, I would greatly appreciate some possibly insight into how best to tackle the problem.

Thank you.

#1
09/21/2010 (4:38 pm)
You can try to push the near plane further,theoretically this will increase the precision,but will clip near objects.
I know that flight sims use split rendering - they render first the far objects,then they clear the depth buffer and render the near ones with a different depth buffer.
#2
09/21/2010 (4:53 pm)
Thanks Ivan, but the problem is not lack of precision in the Z buffer, it is the position of the renderTransform is too large. this effects even objects right in front of the viewer if the object and viewer are say 100000 units from origin.


It could be:

a) D3D9 does not like getting render transforms into the tens of thousands.

b) F32s are not precise enough to go out to 10k distance and lose decimals at this distance, so D3D9 is not getting enough information to have accurate depth buffering.

I can test case b, but obviously changing matrixF from F32s to F64s is a beefy task.
#3
09/21/2010 (5:12 pm)
Are F32s precise enough to go out to 10k distance? A 32-bit float is a sign bit, 8 bits of exponent, and 23 bits of mantissa. You are trashing 14 bits out of the mantissa to represent whole numbers from [0..10k], which leaves you with 9 bits to represent numbers between [0..1]. In other words, there are only 512 steps in between each whole number.

This shit isn't magic, and F64 is not the answer.
#4
09/21/2010 (5:15 pm)
I've noticed this also. Some things I've observed:

It appears to be much more of an issue with T3D than it was with TGEA.

It is not due to z-buffer precision, as it happens even with a nearClip of 1 and a farClip of 100 which should give masses of precision.

Other aspects of the engine such as physics and movement also appear to be affected to some degree when large coordinates are used.
#5
09/21/2010 (5:24 pm)
Ah, so its not a problem with the z buffer at all, but a problem with loss of precision in positions in the 10k area.

With only 512 possible positions between whole numbers more than z battling will go wrong. Collision will get wonky as well.