Three.js: 将3D位置转换为2D屏幕位置

7

我有一个带有位置(x,y,z)的3D对象。如何计算该对象的屏幕位置(x,y)?

我已经搜索了一些解决方案,其中一个是找到投影矩阵,然后将3D位置点乘以此矩阵以将其投影到某个2D视图表面(计算机屏幕)。但我不知道如何在Three.js中找到这个矩阵。

我尝试了一个转换函数,但它给出了错误的结果。

function Point3DToScreen2D(point3D){
            var screenX = 0;
            var screenY = 0;
            var inputX = point3D.x - camera.position.x;
            var inputY = point3D.y - camera.position.y;
            var inputZ = point3D.z - camera.position.z;
            var aspectRatio = renderer.domElement.width / renderer.domElement.height;
            screenX = inputX / (-inputZ * Math.tan(camera.fov/2));
            screenY = (inputY * aspectRatio) / (-inputZ * Math.tan(camera.fov / 2));
            screenX = screenX * renderer.domElement.width;
            screenY = renderer.domElement.height * (1-screenY);
            return {x: screenX, y: screenY};
        }

Thank in advance.

3个回答

12

对我而言,这个函数是可行的(Three.js 版本 69):

function createVector(x, y, z, camera, width, height) {
        var p = new THREE.Vector3(x, y, z);
        var vector = p.project(camera);

        vector.x = (vector.x + 1) / 2 * width;
        vector.y = -(vector.y - 1) / 2 * height;

        return vector;
    }


2
太好了!只需记住project是一个可变方法,因此如果您在现有的Vector3上使用它,请在调用clone之前使用。 - Mistic
当z为0时,它会失败。 - Qiaosen Huang
不应该出错。请提供一些 jsbin/jsfiddle 的例子。 - Julia Savinkova

5
我最终使用以下代码完成:
注意:div参数为canvas DOM元素。
function toScreenXY( position, camera, div ) {
            var pos = position.clone();
            projScreenMat = new THREE.Matrix4();
            projScreenMat.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
            projScreenMat.multiplyVector3( pos );

            var offset = findOffset(div);

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

        }
function findOffset(element) { 
          var pos = new Object();
          pos.left = pos.top = 0;        
          if (element.offsetParent)  
          { 
            do  
            { 
              pos.left += element.offsetLeft; 
              pos.top += element.offsetTop; 
            } while (element = element.offsetParent); 
          } 
          return pos;
        } 

我欣赏你的尝试,因为这是一个似乎没有任何记录解决方案的问题,但我无法获得准确的坐标。 - BishopZ
你能详细说明一下你的情况吗? - user1533481
谢谢,这是我的写作:https://dev59.com/BWgu5IYBdhLWcg3wGTWd - BishopZ
我相信你的不准确坐标问题来自于错误的div(第3个参数)输入。无论如何,看起来你已经找到了答案。恭喜! - user1533481

-1

谢谢回复,李。假设我有一个光线,它的起点是物体的位置,方向指向屏幕。那么这条光线会与哪个物体相交,以便将物体在屏幕上的(x,y)坐标返回给我?谢谢。 - user1533481

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接