使用Projection将World坐标转换为Three.js中的Screen坐标

时间:2012-07-20 20:28:32

标签: javascript 3d three.js

关于Three.js中的unproject,有几个很好的堆栈问题(12),即如何将浏览器中的(x,y)鼠标坐标转换为(x,y) ,z)Three.js画布空间中的坐标。大多数情况下他们都遵循这种模式:

    var elem = renderer.domElement, 
        boundingRect = elem.getBoundingClientRect(),
        x = (event.clientX - boundingRect.left) * (elem.width / boundingRect.width),
        y = (event.clientY - boundingRect.top) * (elem.height / boundingRect.height);

    var vector = new THREE.Vector3( 
        ( x / WIDTH ) * 2 - 1, 
        - ( y / HEIGHT ) * 2 + 1, 
        0.5 
    );

    projector.unprojectVector( vector, camera );
    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
    var intersects = ray.intersectObjects( scene.children );

我一直试图反过来 - 而不是从“屏幕到世界”空间,从“世界到屏幕”空间。如果我知道Three.js中对象的位置,我该如何确定它在屏幕上的位置?

似乎没有任何已发布的解决方案来解决此问题。 Another question about this just showed up on Stack,但作者声称用一个不适合我的功能解决了这个问题。他们的解决方案不使用投影Ray,我很确定,因为2D到3D使用unprojectVector(),3D到2D解决方案将需要projectVector()。

在Github上也开放了this issue

感谢任何帮助。

4 个答案:

答案 0 :(得分:34)

试试这个:

var width = 640, height = 480;
var widthHalf = width / 2, heightHalf = height / 2;

var vector = new THREE.Vector3();
var projector = new THREE.Projector();
projector.projectVector( vector.setFromMatrixPosition( object.matrixWorld ), camera );

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

答案 1 :(得分:7)

对于现代Three.js(r75),可以使用以下项目将矢量投影到屏幕上:

var width = window.innerWidth, height = window.innerHeight;
var widthHalf = width / 2, heightHalf = height / 2;

var pos = object.position.clone();
pos.project(camera);
pos.x = ( pos.x * widthHalf ) + widthHalf;
pos.y = - ( pos.y * heightHalf ) + heightHalf;

答案 2 :(得分:6)

对于每个获得deprecatedwarnings日志的人来说,接受的答案适用于较旧的Three.js版本。现在,它更容易:

let pos = new THREE.Vector3();
pos = pos.setFromMatrixPosition(object.matrixWorld);
pos.project(camera);

let widthHalf = canvasWidth / 2;
let heightHalf = canvasHeight / 2;

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

console.log(pos);

答案 3 :(得分:0)

无法将(x,y)坐标转换为(x,y,z)坐标,因为您丢失了信息。你引用的是如何找到场景中与(x,y)生成的光线相交的所有对象上的所有点。

您要求的从“世界到屏幕”是投影的全部内容,相当于渲染单个点(x,y,z)。你所做的是将投影矩阵应用于你的点(x,y,z)。它可能是http://mrdoob.github.com/three.js/docs/49/#Projector处的Projector.projectVector(vector, camera)函数,但由于它输出了一个3d矢量,我只能假设其中一个维度为0而你可以忽略它。