World coordinates precision issues
by Adam Beer · in Torque 3D Professional · 05/06/2009 (1:37 pm) · 19 replies
I ported my artwork and vehicle class over to T3D, and am having some issues with flickering/jitteryness at higher coordinates. This is definitely worse than the TGEA version on this issue as TGEA wouldnt start showing symptoms until you were in the 9000+ coord range.
Jittering and flickering (z-fighting of close meshes on the model) start even before I reach 1000 units out. I am making a combat flight sim, and this is a really big issue since you need a big area to fly around in. Just wondering if this is a known bug, or if someone knows what might have happened.
Jittering and flickering (z-fighting of close meshes on the model) start even before I reach 1000 units out. I am making a combat flight sim, and this is a really big issue since you need a big area to fly around in. Just wondering if this is a known bug, or if someone knows what might have happened.
About the author
Adam is the owner of Ignition Games, an indie game and software development company.
#2
If I were to scale down the aircraft, wouldnt this effect the near clip place as the camera would be so close to such a small object?
05/06/2009 (1:57 pm)
View distance is set to 16000 right now. Thats probably the issue. I think the only solution to the problem is scaling everything down. This includes the terrain, aircraft and the speed at which they travel. If I were to scale down the aircraft, wouldnt this effect the near clip place as the camera would be so close to such a small object?
#3
You *could* use the MathUtils::getZBiasProjectionMatrix function to get around this some, but I think settings that huge a view distance is kind of crazy anyway.
05/06/2009 (2:36 pm)
With that huge of a view distance, your z-buffer will have terrible precision. Here's a link I found handy when trying to get z-bias projection matrices working for T3D: www.sjbaker.org/steve/omniv/love_your_z_buffer.html It will tell you how much precision you have based on your settings.You *could* use the MathUtils::getZBiasProjectionMatrix function to get around this some, but I think settings that huge a view distance is kind of crazy anyway.
#4
First you render everything from 1000 to 16000 units. Since a near plane of 1000 gives you awesome precision things the far plane go really far out.
Second you render things between 0.001 and 1000 units. Since the far plane is fairly close you get really good precision there.
It would be tricky to work out in Torque 3D and don't know how it would effect things like Advanced Lighting, HDR, etc. But it may be worth trying if you really want a huge environment.
It also may be possible that you can do this only for distant terrain.
05/06/2009 (2:44 pm)
Well another solution which i've been wanting to try, but haven't yet is subdividing the world into two different ranges.First you render everything from 1000 to 16000 units. Since a near plane of 1000 gives you awesome precision things the far plane go really far out.
Second you render things between 0.001 and 1000 units. Since the far plane is fairly close you get really good precision there.
It would be tricky to work out in Torque 3D and don't know how it would effect things like Advanced Lighting, HDR, etc. But it may be worth trying if you really want a huge environment.
It also may be possible that you can do this only for distant terrain.
#5
As you have a vertex shader, you choose what to output to the z interpolators and depth buffers. Combine that with things like floating point depth buffers and there is a lot of ways of getting range more suited to your game.
The classic to try with a float depth buffer is 1-z. This gives you an almost linear depth buffer (like old fashioned w buffers).
05/06/2009 (3:11 pm)
Another trick is to try different Z encoding. As you have a vertex shader, you choose what to output to the z interpolators and depth buffers. Combine that with things like floating point depth buffers and there is a lot of ways of getting range more suited to your game.
The classic to try with a float depth buffer is 1-z. This gives you an almost linear depth buffer (like old fashioned w buffers).
#6
05/06/2009 (3:55 pm)
I have been looking into just scaling everything down for simplicity sake, but the only issue I see with doing that is the camera. You can tell everything has shrunk. I havent tried shrinking the aircraft models yet, but I can guess that if they get small enough, the camera will clip them out. Any idea on how to make the camera allow for really small models as control objects?
#7
I lowered the visible distance to 1000 and got to just X: 400 Y: 400, and the flickering started. Here is what this looks like:

Black parts on the nozzle flicker all over, and anywhere else where separate meshes on the model are closer together. The model worked fine in TGEA, so what could be happening here?
05/07/2009 (2:12 pm)
I decided to dump the scaling everything down idea and just stick to solutions you guys suggested. I did a quick test first to see if the view distance was in fact the cause of the issues, and it turns out it wasnt.I lowered the visible distance to 1000 and got to just X: 400 Y: 400, and the flickering started. Here is what this looks like:

Black parts on the nozzle flicker all over, and anywhere else where separate meshes on the model are closer together. The model worked fine in TGEA, so what could be happening here?
#8
What is your near plane distance right now?
As it is a flight game, there is no reason for it to be small as you won't walk up to walls etc
05/07/2009 (3:17 pm)
Just scaling everything down does not solve the problem, it just moves the problem from "too large value for the precision" to "too small values for the precision", at least if the amount of scaledown for the models was about the same as the factor by which you reduced the far dist / near dist ratio.What is your near plane distance right now?
As it is a flight game, there is no reason for it to be small as you won't walk up to walls etc
#9
The farther out from the world origin you go, the more it flickers and it will start to flicker at around 400 units out.
05/07/2009 (3:22 pm)
Well the thing is now, what was originally said to be the issue (z-buffer precision) is in fact not what is causing the problem I outlined. Like I said in my post above, the visible distance was lowered to a normal value, and that didnt solve the flickering. The farther out from the world origin you go, the more it flickers and it will start to flicker at around 400 units out.
#10
05/07/2009 (3:35 pm)
@Adam, well, you should still try increasing the near plane distance, as that gives you more precision back than decreasing the far plane, IIRC.
#11
This is what I found that makes sense to change:
mLastCameraQuery.nearPlane = 0.01f;
05/07/2009 (3:41 pm)
That change would occur in guiTSControl.cpp correct?This is what I found that makes sense to change:
mLastCameraQuery.nearPlane = 0.01f;
#12
05/07/2009 (4:54 pm)
@Adam - Actually that looks like self shadowing artifacts. Go to your Sun object and try adjusting the 4 'overDark' parameters... they are in the order of the shadow cascades nearest to furthest.
#13
05/07/2009 (5:01 pm)
That didnt make it any better. Of course, I dont understand what those parameters do, so my changes might not have helped. What would be a good setting for me?
#14
05/07/2009 (5:56 pm)
@Adam - If the values are already really high.... 2000 or more... go lower... if they are under 1000 try it higher. There is no scale or right value for this ... other than one that doesn't produce artifacts in your scene.
#15
I believe the proper solution is to separate rendering coordinates and gamecode coordinates. There is no reason the rendering client needs to "know" that the plane is at 10000,10000,2000... it just needs to figure out where to draw everything in the scene relative to the eye point.
09/20/2010 (3:14 am)
Your problem is not view distance or shadows, it is how large your position xyz values are. Above 1000, it gets very jittery. Above 100,000, everything flickers uncontrollably. This is as has been pointed out due to Z buffer issues, the Z buffer probably gets overloaded when numbers become that large.I believe the proper solution is to separate rendering coordinates and gamecode coordinates. There is no reason the rendering client needs to "know" that the plane is at 10000,10000,2000... it just needs to figure out where to draw everything in the scene relative to the eye point.
#16
What would be the best solution to extend the range out to say 50k units or more? I know there have been some ideas here, but im looking for something that would be feasible and not cost me an arm and a leg to hire someone to do.
09/20/2010 (5:16 am)
This issue is still haunting me and I really need to come up with some kind of solution. It turns out that our 28km x 28km worlds arent big enough. I did a test tonight trying to fly out to 42 km and the shaking in the cockpit and the z-fighting on the meshes were terrible.What would be the best solution to extend the range out to say 50k units or more? I know there have been some ideas here, but im looking for something that would be feasible and not cost me an arm and a leg to hire someone to do.
#17
So for example, if we have a plane at 12000,-14000, 10000 and our camera position is at 10000,-13000, 10000 we can just pretend the plane is rendering at 2000, -1000, 0 - it will look the same either way, but the latter case should not confuse the z buffer.
09/20/2010 (7:28 am)
my idea is to set all x y z coordinates relative to the camera, not the middle of the world, just before sending them to render on the client. The client rendering system does not need to know it isn't at the center of the world.So for example, if we have a plane at 12000,-14000, 10000 and our camera position is at 10000,-13000, 10000 we can just pretend the plane is rendering at 2000, -1000, 0 - it will look the same either way, but the latter case should not confuse the z buffer.
#18
Any Torque gurus know what would be the easiest, sneakiest way to do that? Thank you! :)
09/20/2010 (5:02 pm)
Ideally, we would want to sneak in right before all the renderable coordinates get passed to D3D9, and redo all of the xyz coordinates to be relative to the front of the view frustum.Any Torque gurus know what would be the easiest, sneakiest way to do that? Thank you! :)
#19
That seems to be what most child classes call up to for the mRenderObjToWorld matrix to be generated?
09/20/2010 (6:25 pm)
Wouldn't the easiest place here to much with things be in SceneObject::setRenderTransform()?That seems to be what most child classes call up to for the mRenderObjToWorld matrix to be generated?
Torque 3D Owner Marc Dreamora Schaerer
Gayasoft
The more its out of scale (anything above 10000 - 15000), the larger the direct impact is on the depth buffer, which is causing the issue you are seeng.
For a flight game, you could also do what Star Trek / Futurama do ;)
Not the ship moves, the world does, at least in the horizontal case above the ground
That way you have full precision at any given time.