Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Precision issue with r49 #1898

kovleouf opened this Issue · 24 comments

4 participants


I updated my Three lib to r49 but i'm dealing with many precision issue when rendering my old scene (it was working fine with r48).

The issues only occur when rendering far away from the world origin (further than 2 000 000 on some axis).

1st : my ground is formed of many Meshs built with PlaneGeometry and i now have some 1 pixel width holes between my meshs when moving the camera.

2nd : i'm dealing with a strong precision issue (>50 world unit error) when using projector and Matrix / Vector multiplication.

I tried to revert the Matrix optimization stuff but i didn't manage to get it working with all the function change in this release :-/


Can you share ascreenshot?


i'm sorry but i can't show more than this partial screenshot (with a red background to see the holes):

These holes are not always visible depending on the camera distance/angle.
The camer target is x = 538711, y = 5742553, when i move near the world origin there is no issue.

NB: i didn't change the webgl renderer precision (still highp)


Hmmm, this is interesting / bad.

I wonder if this is just some bug introduced by optimizations or there is something inherently different when doing math directly on typed arrays instead of JS floats (if I remember well, these are rather large, not sure if types match).

BTW precision specifier shouldn't matter on desktop GPUs, it's supposed to be just for mobile ones.

Edit: Yup, found it. JS numbers are 64 bit floats while new optimized Matrix4 uses 32 bit float typed arrays.

I wonder how much of performance gain actually came from this instead of from typed arrays themselves.

@mrdoob I don't think we should switch to Float64Array everywhere but maybe it could be optional?

@kovleouf Could you try to change these lines to use Float64Array to see if it helps for you?


Using Float64Array lead to this error on 1st frame :

Uncaught TypeError: Type error in WebGLRenderer.js:4754


I beleive support is missing for Float64Array in firefox


I'm using Chrome 18.0


Ah no, I think it's because now we send Matrix4's typed arrays directly to WebGL and there it must be 32 bit floats again.

Hmmm, you would need to cast these somehow.

@gero3 Firefox supports Float64Array. It's in typed array specs and I just checked in console ;)


Ah I'll look into it, then.
It will probably not get much slower by changing the matrixes and casting it later. But I have to look into it.


Hmmm, Float32Array vs Float64Array performance seems quite surprising:

May be worth to try 64 bit floats?



This is my first try on it. As I expected that float64array would be at least as fast as float32


I'm getting much lower performance with 64 bit floats - 35 fps vs 60 fps on webgl_performance stress test (using @gero3's commit).


I tried with @gero3's commit and it fixes my precision issues.


Yay! So I guess this should be toggleable by some flag (with default set to use Float32Array).

@mrdoob Maybe something like this?

THREE.FloatArrayType = Float32Array;
THREE.FloatArrayType = Float64Array;

Not sure though how to override this nicely from the application layer, there are objects which are created simply by including the lib, so these must be somehow aware of the override :/.

It could be something like this, but it's quite ugly:

var THREE =  { FloatArrayType: Float64Array };

<script src="../build/Three.js"></script>

And then inside Three.js:

if ( THREE.FloatArrayType === undefined ) {

    THREE.FloatArrayType = Float32Array;


And in Matrix4:

this.elements = new THREE.FloatArrayType( 16 );

Maybe something like THREE.Matrix4.set64bit()? which would set a static flag that every matrix would check at instantiation time. It's basically Matrix4, right?


Matrix4 and Matrix3.

But trouble are static matrices that are created at lib loading time - if we set it like this, they would have been already created in a different way and thus incompatible :S.

Now we could reset these in THREE.Matrix4.set64bit() but this would be also bad design, fragile as we would need to collect all such static matrices there.



@kovleouf would anything change if you divided all your values by 1000?


@mrdoob Another option could be doing this at the build time (we would build the lib with either 32 or 64 bit typedef file included).

Then we would have a special version of the lib Three64.js, to be used if application needs higher precision (somehow similar to how binary applications have 32 and 64 bit versions).

@kovleouf Sanity check - do you use proper mathematical constants everywhere?

For example I remember having precision artefacts when I used numbers like 3.14 instead of Math.PI. This was ok when my scenes were small, but on large scenes imperfections were popping up (especially treacherous were rotations of larger planes, tiny angular difference can make a huge displacement).


So seems like the only option is having it run slower. I wonder if that's ok with @kovleouf or whether there's something that he can do on his app code instead ;)


@mrdoob : i can't divide everything by 1000 because i'm working on an earth map using real lon / lat coordinate system so it would be a pain to convert everything.

@alteredq : i'm using Math.XXX constants, the precision error is due to the huge size of my world.

I will investigate the performances with r48, r49 32bits and r49 with the quick 64bits hack today


I'm running with 6-10 ms / frame on r48 and r49 and 10-15 ms / frame on r49 with float64Array.

I think i'll keep my project under r48 for now


What browser/system is that on?


Window XP SP3
Intel core 2 Duo 2.4Ghz
3.50 Go RAM
GeForce GTX 260 Ultra
Chrome 18.0.

I tried with the 2nd version of @gero3 (Pull Request #1903) and i'm running with 8-12ms / frame. (i can't give a real FPS because i refresh the frame only when something changes)


So you get 6-10ms with Number, 10-15 with Float32Array and 8-12 with Float64Array?


no :
6-10ms with Number
6-10ms with Float32Array but precision issue
8-12ms with Float64Array and conversion code to prevent precision issue

@mrdoob mrdoob closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.