Strange result from unproject method


I’m trying to move mesh so that its centre is located at the top left corner of the item div.

I have noticed that when I set the mesh’s position inside animate, it moves to where I want it, as shown in the first image. However, when I move the code to set mesh’s position outside animate, I get the result shown in the second image. This is confusing to me since I assumed that point, the mesh’s new position, would be constant regardless of where it is defined. But this turns out not to be the case. Through analysis, I found that the line ray.unproject(camera) is the reason for this discrepancy. ray’s z value changes when I move the six lines outside the animate function. I don’t understand why.

Does anyone know why this is happening? My end goal is to animate the mesh moving in a curving pattern outside the item div, which I plan to do using gsap. I figure I just need to call outside the animate function, which has worked in my experiments so far, but if this would not be the ideal way to achieve what I want, then I’d be happy to hear suggestions.

const item = document.querySelector(".item")
const topX = item.offsetLeft;
const topY = item.offsetTop;
const x = (topX / window.innerWidth) * 2 - 1;
const y = - (topY / window.innerHeight) * 2 + 1;
const ray = new THREE.Vector3();
const point = new THREE.Vector3();

function animate() {
    // Move sphereMesh to the 3d point corresponding to pixel coordinate (x,y)
    ray.set(x, y, 0.5);
    ray.unproject(camera); // this line changes whether inside/outside animate()
    const distance = - camera.position.z / ray.z;

    renderer.render(scene, camera);


Output when mesh’s position is set inside animate:

Output when mesh’s position is set outside animate:

Would it be possible to share a live debuggable example with both cases? I’m not sure I can find the problem, but I’m curious to see it by myself.


  • when I try unproject inside render loop and outside render loop, the values are identical, so there is something in your code that I do not have in my test case
  • I’m not sure I understand the logic of the calculations (for example, distance uses Z of non-normalized camera position, and Z ot normalizes ray)