Skip to main content
Up and Coming
April 29, 2013

Floating point precision issues

Just as an warning, my game started to have some visible issues after the position values get larger than 5000, the headtracking lost a bit of smoothness and closer to camera objects seems to shake a bit, on a regular camera/monitor setup these kind of artifacts only gets visible on much larger values, however I think due to nature of the VR setup, seems that precision became a issue much sooner than I expected.

Anyone have any ideas on how to handle mitigate this?
    This topic has been closed for replies.

    24 replies

    Inspiring
    April 27, 2017
    I've read through all those things and understand the cause of the problem. What I don't understand get is why we would see the issue at a position of say, (800,0,0) but not at (400,0,0). 400 and 800 have the same precision.

    Are you suggesting that some kind of mathematical operation is being performed on the (800,0,0) position that would push it to require an additional bit of precision, which thereby causes the jitter due to a shift from mm to cm precision?
    Inspiring
    April 27, 2017
    Yes. While ideally the error of head tracking, physics, and animation could just double with each doubling of distance, it actually grows faster than that when a calculation amplifies it or uses multiple arguments with error. If you have seen an increase in jitter at 800 units, it probably means Unity's model or view matrix code has somehow become more sensitive to floating point error. It seems reasonable to expect error below .001 up to 1000 units from the origin, so you might want to click Help > Report a bug... to let Unity know about this.
    kojack
    Honored Contributor
    April 28, 2017
    At 10000m (from the year ago part of the thread), the precision of floats would be 0.9765mm. Now while a fraction off from 1mm precision doesn't sound so bad, as it passes through the world/view/projection matrix, errors will be compounded.

    Frame rate is going to affect that too. At 90fps, moving your head 1cm to the side over 1 second requires a precision of 0.1mm to be smooth over all frames. If you are 10000m from the origin, then moving 1cm over 1 second will look like your frame rate is 10.24 fps, because if can't represent all 90 frames as unique positions.

    There's also prediction calculations going on to smooth out the sensor fusion (IMU data at hundreds of frames per second and much slower camera data). And time warp distortions, etc. Lots of maths happen to do a VR render.




    400 and 800 have the same precision.


    At 400 you have a precision of 0.0000305. (30.5uM)
    At 800 you have a precision of 0.000061. (61uM)


    To see these values, you can use the C++ function nextafter(). You give it a float (there's a double version too) and it tells you next value after that float. The difference between those two floats is the precision at that range.

    It's really fun for space sims. At 1AU (distance from the sun to the earth), floats have a precision of 16.384KM!
    That's why for space I'd use fixed point instead of floats. A 54:10 fixed point number would have 0.9765mm precision equally spread over 1.9 light years, instead of just 10KM.
    (Fixed point has a single precision over the entire range of the number, while floating point has a decreasing precision as the number gets bigger)



    Author: Oculus Monitor , Auto Oculus Touch , Forum Dark Mode , Phantom Touch Remover , X-Plane Fixer Hardware: Threadripper 1950x, MSI Gaming Trio 2080TI, Asrock X399 Taich Headsets: Wrap 1200VR, DK1, DK2, CV1, Rift-S, GearVR, Go, Quest, Quest 2, Reverb G2, Quest 3
    Inspiring
    April 28, 2017
    Thanks for the explanation! Turns out due to the way we are using Unity animations, we can't use the floating origin solution. We have animation keys that tell the camera's parent object (which starts at the origin) to move to a location outside the precision boundary (such as (-4000,0,0)). Since those values are outside the precision boundary and unity doesn't seem to provide an easy way at runtime to edit animation keys, we have to use a different solution (keeping the object the camera is childed to stationary, and moving the rest of the world).