Model moves in a very jerky way the further it is from the origin

Not exactly a scripting issue, but I’m new to the world of 3D dev so not really sure where to start investigating this one.

So far I just have a task that moves my satellite 0.5m/s in the x direction. If I’m close to the origin, everything is fine, but if I place my satellite at ~ 0, 100000, 0, then it starts being jerky as it moves, and if I place it 10x further away, it’s even jerkier.

I’ve tried disabling as many things as possible to isolate the issue. I’ve removed the other models, I commented out simplepbr, I even commented out all the lights and I still see the same behavior.

What might be causing this? Or if you have some tips on where you might look I would appreciate that as well.

At 500,000 away from the origin (along the Y axis, not that that should make a difference)
500000 away

At 5,000,000 away from the origin
further away

I also tried doing this with the cube to eliminate the idea that the model is the source of the issue but I got the same thing.

Welcome to the wonderful world of limited floating point precision :slight_smile:

This is sadly a common issue when you have objects far far away from the origin, you reach the limit of the single precision floating point variables : because you have huge values, the “lower” digits are simply truncated to fit into the mantissa (roughly speaking in single precision you can store about 6-7 digits in the mantissa). So, the actual position becomes jerky due to this truncation.

Two solutions:

Move the origin as close as possible to your object to make the position value more compatible limited precision. Usually this is done by putting the camera at the origin and move everything relative to it.

Rebuild Panda3D to use double precision by default, but you would still have precision issue when getting really far away, also this does not solve precision issue inside the GPU, mainly the depth buffer, where everything will still be 24/32 bits.

In my app Cosmonium I had to implement both solution (as well as some even more complicated) because of this.

1 Like

Are you sure? Just O(100000) away from the origin? But also, the object appears to be jittering in y and z directions as well, but there’s no change in those, I’m only moving it along x (for now anyway). I’ll try recompiling with double and seeing if that helps.

There is not one source of jittering but quite many. The actual position of the object is stored in single precision float, the transformation matrix, the projection matrix of the camera, … Then you enter the realm of the GPU where you have even more source of loss of precision.

In your case, I believe this is the depth buffer which cause the jittering in all direction? The depth is the distance to the camera, projected onto the near-plane far-plane interval. On many GPU, the default precision of the depth buffer is not 32 bits but instead 24 bits. When rendering a scene, you should limit your scene to what is actually near the camera to maximize the precision of the depth buffer, so first rule is to adjust the near and far planes to maximize the precision of your interval, then if that’s not enough keep the camera fixed at (0, 0, 0) and move the whole scene around it.

There are dozen of other tricks to help resolving this (log depth buffer, 1/z depth buffer, non linear perspective, multipass rendering, …), but there are no magic bullet and each technique has its own drawback (I’ve tested them all, trust me :p). But first, optimize the precision of the depth buffer, then only if that does not work go and look for additional tricks.

1 Like

Recompiling with double made everything butter smooth, even out to O(1,000,000,000) (I didn’t test further than that). Thanks for the tip, and for all the other suggestions, I’ll keep them in mind as I suspect this won’t be the last time I deal with jitter.