用three.js提取3D点的2D屏幕位置

时间:2015-12-11 00:36:52

标签: javascript 3d three.js

我想弄清楚如何获得3D点的2D屏幕坐标。

我正在使用three.js来生成一些在屏幕上慢慢下降的雪花。我最初编写脚本就像一个2d画布动画并添加了鼠标交互,所以你可以用鼠标移动吹雪。它工作得很好,但是当切换到webgl时,雪花现在被表示为3D点,并且获得鼠标到每个粒子的距离使得离屏幕中心更远的粒子由于透视而以不期望的方式表现。

http://www.simplemathguild.com/snowtest.html

1 个答案:

答案 0 :(得分:0)

您需要做的是通过viewProjection矩阵转换worldPos vec3,然后执行透视除法。这将它带到NDC空间,其中(-1,-1,x)=屏幕左下角,(+ 1,+ 1,x)=屏幕右上角。根据屏幕宽度和屏幕高度进行调整,屏幕空间中的坐标为。

在代码中,这就是它的样子:

worldToScreen: function(viewProjectionMatrix, screenWidth, screenHeight){
    var m = viewProjectionMatrix;
    var w = m[3] * this[0] + m[7] * this[1] + m[11] * this[2] + m[15]; // required for perspective divide
    this.transformByMat4(viewProjectionMatrix);
    if (w!==0){ // do perspective divide and NDC -> screen conversion
        var invW = 1.0/w;
        this[0] = (this[0]*invW + 1) / 2 * screenWidth;
        this[1] = (1-this[1]*invW) / 2 * screenHeight; // screen space Y goes from top to bottom
        this[2] *= invW;
    } 
    return this;
}

顺便说一下,这就是GPU在渲染内容的过程中所做的事情,减去NDC到屏幕坐标转换。

检查三种Vector3方法,很可能是在那里实现的,或者只使用上面的代码片段。