使用投影在Three.js中将世界坐标转换为屏幕坐标

问题描述:

有关Three.js中的未投影的几个优秀堆栈问题(1,2),即如何将浏览器中的(x,y)鼠标坐标转换为(x,y,z)坐标在Three.js画布空间中。他们大多遵循这个模式:使用投影在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,但作者声称用一个不适合我的功能解决了这个问题。他们的解决方案不使用投影射线,并且我确信从2D到3D使用unprojectVector(),3D到2D解决方案将需要projectVector()。

也有this issue Github上打开。

任何帮助表示赞赏。

+0

非常感谢“屏幕到世界”翻译模式。这是一个痛苦好几个小时.. – LePhleg 2014-04-17 02:54:49

尝试这样的:

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; 
+0

在另一个堆栈问题发布此链接,也有解决方案。再次感谢! https://github.com/mrdoob/three.js/issues/78 – BishopZ 2012-07-24 15:13:12

+2

getPosition()已被弃用。改为: var vector = projector.projectVector(new THREE.Vector3()。getPositionFromMatrix(object.matrixWorld),camera); – imbrizi 2013-06-02 01:17:29

+0

已被更新回答。谢谢@imbrizi! – mrdoob 2013-07-01 02:22:31

不能因为丢失了信息,将(x,y)坐标转换为(x,y,z)坐标。你所引用的是如何找到场景中与(x,y)所产生的射线相交的所有物体上的所有点。

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

对于现代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; 

对于大家越来越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); 
+0

“对象”未定义 – 2018-01-31 16:31:42