将3D位置转换为2d屏幕位置[r69!]

Dar*_*nns 26 3d 2d coordinates three.js

我需要Three.js代码将3D对象坐标转换为'div'元素中的2d,以便我可以将文本标签放置在需要的位置(没有那些标签缩放/移动/旋转以及3D移动).不幸的是,到目前为止我见过和尝试过的所有示例似乎都在使用过时的函数/技术.就我而言,我相信我使用的是R69 of Three.js.

这是一个"老"技术的例子,它只会给我带来错误:

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

下面是一些新代码(?)的片段,它没有为我提供足够的上下文工作,但看起来更清晰:

https://github.com/mrdoob/three.js/issues/5533

mei*_*irm 36

我为我的项目编写了以下函数; 它接收一个THREE.Object3D实例和一个摄像头作为参数,并返回屏幕上的位置.

function toScreenPosition(obj, camera)
{
    var vector = new THREE.Vector3();

    var widthHalf = 0.5*renderer.context.canvas.width;
    var heightHalf = 0.5*renderer.context.canvas.height;

    obj.updateMatrixWorld();
    vector.setFromMatrixPosition(obj.matrixWorld);
    vector.project(camera);

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

    return { 
        x: vector.x,
        y: vector.y
    };

};
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个THREE.Object3Djust以保持div位置(它附加到场景中的网格),并且在需要时可以使用该toScreenPosition函数轻松转换为屏幕位置,并更新div元素的坐标.

var proj = toScreenPosition(divObj, camera);

divElem.style.left = proj.x + 'px';
divElem.style.top = proj.y + 'px';
Run Code Online (Sandbox Code Playgroud)

这里有一个演示小提琴.

  • 请记住,`canvas.width` 和 `canvas.height` 可能无法反映画布的真实宽度和高度,尤其是在全屏应用中。然后改用`getBoundingClientRect`。 (2认同)

Wes*_*ley 22

您可以使用如下模式将3D位置转换为屏幕坐标:

var vector = new THREE.Vector3();
var canvas = renderer.domElement;

vector.set( 1, 2, 3 );

// map to normalized device coordinate (NDC) space
vector.project( camera );

// map to 2D screen space
vector.x = Math.round( (   vector.x + 1 ) * canvas.width  / 2 );
vector.y = Math.round( ( - vector.y + 1 ) * canvas.height / 2 );
vector.z = 0;
Run Code Online (Sandbox Code Playgroud)

three.js r.69

  • 抱歉.错字固定.问题是关于将3d位置转换为屏幕空间. (3认同)
  • 这看起来比以前的建议简单得多!但是,我很困惑:引用的对象在哪里——我们希望将其 3D 坐标转换为 2D 坐标? (2认同)

Jul*_*ova 7

对我来说这个功能有效(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;
    }
Run Code Online (Sandbox Code Playgroud)