extracting the 2D screen position of a 3D point wi

2019-09-14 21:27发布

This question already has an answer here:

I am trying to figure out how to get the 2D screen coordinates for a 3D point.

I am using three.js to generate some snowflakes that fall slowly down the screen. I originally wrote the script just as a 2d canvas animation and added mouse interaction so you could blow the snow around with mouse movement. It worked well, but when switching to webgl the snowflakes were now represented as 3D points and getting the distance of the mouse to each particle makes particles further from the center of the screen behave in an undesired way because of the perspective.

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

1条回答
The star\"
2楼-- · 2019-09-14 22:01

What you need to do is to transform your worldPos vec3 by the viewProjection matrix and then perform the perspective divide. This brings it to NDC space where (-1,-1,x) = bottom left of your screen and (+1,+1,x) = upper right of your screen. Adjust this by your screen width and screen height and you have the coordinate in screen space.

In code, this is what it looks like:

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;
}

Btw this is what essentially what the GPU is doing under the hood to render stuff, minus the NDC to screen coordinate conversion.

Check the THREE Vector3 methods, very likely it is implemented there, or just use the code snippet above.

查看更多
登录 后发表回答