Vector3.unproject(camera) returns NaN

I am trying to convert 2d canvas coordinates to 3d .

Vector3.unproject(camera) returns NaN on some machines.

Code

export const convertNormalizedToWorldCoordinates = (vector, currentCameraTHREE) => {


  const vv = vector;
  console.log('%c 🧀 vv: ', 'font-size:20px;background-color: #3F7CFF;color:#fff;', vv);
  vv.unproject(currentCameraTHREE);
  console.log('%c 🍞 vv: ', 'font-size:20px;background-color: #ED9EC7;color:#fff;', vv);


  let dir = vv.sub(currentCameraTHREE.position).normalize();


  let distance = -currentCameraTHREE.position.z / dir.z;

  const pos = currentCameraTHREE.position
    .clone()
    .add(dir.multiplyScalar(distance));

  return pos;
};

Platform:

  • Device: [Desktop]
  • OS: [Ubuntu 20.04]
  • Browser: [Chrome]
  • Three.js version: [0.129.0]

Which values of x y z is showing “vv” in console?

EDIT: oops, just spotted you are using unproject not project - but in any case the two methods are pretty similar so this might still be the same issue

I encountered this problem in a project recently. I haven’t been able to work out what causes it yet so here’s my workaround:

const v1 = new Vector3();

const objectPos = v1.setFromMatrixPosition(el.matrixWorld);
objectPos.project(camera);

// replace any NaN with zeros
objectPos.set(
    Number.isNaN(objectPos.x) ? 0 : objectPos.x,
    Number.isNaN(objectPos.y) ? 0 : objectPos.y,
    Number.isNaN(objectPos.z) ? 0 : objectPos.z
);

It happens intermittently when v1 contains normal values (i.e. small numbers, not Infinity or NaN) so I guess it must be something to do with my camera settings.

However all the camera matrices seem to contain normal values too and in the meantime, setting the NaN values to zero gives the correct results for me so I haven’t investigated further yet.

If you look at the method:

unproject( camera ) {

	return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );

}

You can see it depends on the camera.projectionMatrixInverse, camera.matrixWorld, and your vector vv. So you can also check all of these to see if they contain invalid data (NaN, Infinity, or worse).


Values before unprojecting are : Vector3 {x: 0.6000000000000001, y: 0.20999999999999996, z: -1}
Post: Vector3 {x: NaN, y: NaN, z: NaN}

But interestingly, the same code works on different systems just fine.

Check on other machines there nan what is values x y z before unproject

why dont we get the elephant out of the room 1st by logging currentCameraTHREE.projectionMatrixInverse.elements and currentCameraTHREE.matrixWorld.elements

1 Like

I have this exact same issue. I have a Vector3 with data

Object { x: 0.16484374999999996, y: 0.23114242911898475, z: 0 }

When I then do vec.unproject(camera), I get the following Vector3:

Object { x: NaN, y: NaN, z: NaN }

@makc3d to your question, I have the corresponding values:

camera.projectionMatrixInverse.elements 
Array(16) [ NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, … ]

and

camera.matrixWorld.elements 
Array(16) [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, … ]

How do I find out why my camera.projectionMatrixInverse.elements values are all NaN?

@looeee , your workaround doesn’t work for me. Do you have another solution?

This suggests that invalid data is being passed to the camera somewhere. What does camera.projectionMatrix look like?

If you check the source code for camera.updateProjectionMatrix you’ll see all the inputs used in this function (near, far, aspect, and so on). Check all these too to try and find where the invalid data is coming from.

1 Like