# unproject – How to get the real position on ‘screen(top, left)’ of specific 3d object?

Upon examples, I knew there’s some way to project one point on screen’s (x, y) to ‘3d”s points. But I can’t figure out how to translate it back. Thanks for any clue.

## 4 thoughts on “unproject – How to get the real position on ‘screen(top, left)’ of specific 3d object?”

1. Anonymous says:

Yeah, camera.matrix needs to be replaced now with camera.matrixWorldInverse.
Try with this:

toScreenXY: function ( position, camera, jqdiv ) {

var pos = position.clone();
projScreenMat = new THREE.Matrix4();
projScreenMat.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
projScreenMat.multiplyVector3( pos );

return { x: ( pos.x + 1 ) * jqdiv.width() / 2 + jqdiv.offset().left,
y: ( - pos.y + 1) * jqdiv.height() / 2 + jqdiv.offset().top };

}
2. Anonymous says:

fine…yet mr doob himself put code, so what gives?

3. Anonymous says:

Incase anyone still needs this after upgrading…

function screenXY(obj){

var vector = obj.clone();
var windowWidth = window.innerWidth;
var minWidth = 1280;

if(windowWidth < minWidth) {
windowWidth = minWidth;
}

var widthHalf = (windowWidth/2);
var heightHalf = (window.innerHeight/2);

vector.project(camera);

vector.x = ( vector.x * widthHalf ) + widthHalf;
vector.y = - ( vector.y * heightHalf ) + heightHalf;
vector.z = 0;

return vector;

};
4. Anonymous says:

Ok, very old issue, but I had a nested object, which didn’t work with the above code.
My case was: I wanted the real x-and-y (and z) position for a nested object after rendering, so I adapted the above examples.

1. You now give the whole object as an argument instead of only the object.position in the above examples.
2. Also this will only work after the renderer has done it’s job and called
3. It also works for non-nested objects, but it will do a few calculations too many.
4. It also gives you a screen-Z, which can be used to sort domElements or zSort labels.
The screen-z relative is between 0 and 1, relative to the front and back clipping planes of the camera/renderer and this works fine for my purposes (sorting).
5. You can get the renderers current width and height by renderer.domElement.width and renderer.domElement.height.
scene.updateMatrixWorld();

and

parent.updateMatrixWorld();

function nestedObjecttoScreenXYZ(obj,camera,width,height)
{
var vector = new THREE.Vector3();
vector.setFromMatrixPosition( obj.matrixWorld );
var widthHalf = (width/2);
var heightHalf = (height/2);
vector.project(camera);
vector.x = ( vector.x * widthHalf ) + widthHalf;
vector.y = - ( vector.y * heightHalf ) + heightHalf;
return vector;
};

typical call:

var screenpos=NestedObjecttoScreenXY(object,camera,renderer.domElement.width,renderer.domElement.height,true);

Just in case anyone runs into the same problem.