Search code examples
three.jsprecisionshakelargenumberjitter

Can I Increase Vector Precision in THREE.js?


In THREE.js, I occasionally find myself wishing for better control over vector precision, especially when working with large floats, such as in a solar system. Is there any way to do this?

In the linked example, I'm building a simple solar system with realistic numbers for planet size and distance. To simulate orbit, the entire system rotates upon a pivot located at the position of the planet. When the camera is brought close to the horizon of the planet, positional jitter is apparent along the edge.

Can I increase the precision of the rotation applied to the pivot object and its child objects so this jitter won't be so pronounced? Or do I just need to work with a smaller range of numbers?

http://jsfiddle.net/Angrypickle/5zs8eLoj/72/

When smaller numbers are used for the following vectors, jitter seems lessened.

sun.position.set( 50000000, 0, 0 );
planet.position.set( -50000000, 0, 0 );

Solution

  • After much research, the short answer to the question "Can I increase Vector precision in THREE.js" is yes, but it an advanced subject.

    The long answer is: Increasing Vector precision basically means increasing JavaScript Number precision because the x, y, z, and w values inside the Vector are regular JavaScript Numbers.

    Increasing number precision requires accounting for "epsilon" which is a measurement of potential errors in calculations. See: http://mathjs.org/docs/datatypes/numbers.html for a description and possible solution. Epsilon is present in JavaScript math because of the limitation of 64 bits of storage for Numbers.

    With respect to the precision given to 3D objects at various distances, you can use a Logarithmic Depth Buffer to improve the way object depth ( or Z index ) is handled. It is not linear as one might expect. This is a great way to handle scenes where you need good resolution at distances both near and far.

    Here are 2 good places to start if you decide to implement this solution. See:

    stackoverflow: Logarithmic Depth Buffer OpenGL

    Outerra: Maximizing Depth Buffer Range and Precision

    I originally asked this question because I was seeing "shake" or "jitter" in my objects' positions when using the range of numbers you would find in a solar system. I did not want to scale down my numbers because of the work involved, so I investigated this as a solution. The end result to my efforts is the knowledge that for the purposes of my solar system in THREE.js, there is a limitation to the distances I can use between objects. Because of my geometry, I cannot use distances greater than 6 significant digits, which means for example that Mercury's usual orbit radius of 57.9 million KM must be scaled down to 57.9 thousand KM, which means that the sun will be much closer and larger, and require scaling itself, and so on. Basically, to get reliable positioning, my solar system can only be 999,999 KM in diameter.