翻译为世界坐标 [英] Translation to world coordinates

查看:138
本文介绍了翻译为世界坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有鼠标坐标:mousePos,矩阵视图view和透视投影矩阵pMatrix.

I have mouse coordinates: mousePos, a matrix view view, and a perspective projection matrix pMatrix.

我将坐标转换为世界:找到逆投影矩阵和逆矩阵视图,然后乘以鼠标的坐标.原点的坐标为z = 4,终点的坐标为z = -100.

I translate the coordinates into the world: I find the inverse projection matrix and the inverse matrix view and multiply by the coordinates of the mouse. The coordinates of the origin is z = 4, the coordinates of the end is z = -100.

在第一种情况下,我得到坐标mouseDir1 = (-0.1985 0.02887 4),在第二种情况下我得到坐标mouseDir2 = (-0.1985 0.02887 -100).

In the first case, I get the coordinates mouseDir1 = (-0.1985 0.02887 4), and in the second case mouseDir2 = (-0.1985 0.02887 -100).

为什么坐标x, y相同?

private Vector3f getCoord(MouseInput mouseInput,float z){
        int wdwWitdh = 640;
        int wdwHeight =640;

        Vector2d mousePos = mouseInput.getCurrentPos();
        float x = (float)(2 * mousePos.x) / (float)wdwWitdh - 1.0f;
        float y = 1.0f - (float)(2 * mousePos.y) / (float)wdwHeight;

        Matrix4f invProjectionMatrix = new Matrix4f();
        invProjectionMatrix.set(pMatrix);
        invProjectionMatrix.invert();
        Vector4f tmpVec = new Vector4f();
        tmpVec.set(x, y, z, 0);
        tmpVec.mul(invProjectionMatrix);
        tmpVec.z = z;
        tmpVec.w = 0.0f;

        Matrix4f viewMatrix = new Matrix4f().set(view);
        Matrix4f invViewMatrix = new Matrix4f();
        invViewMatrix.set(viewMatrix);
        invViewMatrix.invert();
        tmpVec.mul(invViewMatrix);
        Vector3f mouseDir1 = new Vector3f();
        mouseDir1.set(tmpVec.x, tmpVec.y, tmpVec.z);

        ///ТЕСТОВАЯ ПРОВЕРКА Z=-100;
        //конеч координаты луча
        Vector4f tmpVec1 = new Vector4f();
        tmpVec1.set(x, y, -100, 1.0f);
        tmpVec1.mul(invProjectionMatrix);
        tmpVec1.z =-100f;
        tmpVec1.w = 0.0f;
        tmpVec1.mul(invViewMatrix);
        Vector3f mouseDir2 = new Vector3f();
        mouseDir2.set(tmpVec1.x, tmpVec1.y, tmpVec1.z);
        System.out.println();
        return mouseDir1;
    }

输出射线:

推荐答案

通常,您应该使用

In general you should use Matrix4f.unproject, so as @httpdigest demonstrated in his answer.

所以我想重点介绍背景:

So I want to focus on the background:

为什么坐标x,y相同?

Why are the coordinates x, y the same?

坐标是相同的,因为源的xy坐标是相同的,并且在与反投影矩阵相乘后无需进行透视划分.操作mul不执行透视除法,它将Vector4f转换为Matrix4f,结果也为类型Vector4f.

The coordinates are the same, because the x and y coordinates of the source are the same and you do no perspective divide after the multiplication by the inverse projection matrix. The operation mul performs no perspective divide, it transforms a Vector4f by a Matrix4f and the result is a of type Vector4f too.

此外,您要乘以反投影矩阵的源坐标必须是规范化的设备坐标,其中xyz的范围为[-1.0,1.0]. z=-1.0是最小深度(近平面),而z=1.0是最大深度(远平面).

Further, the source coordinates, which you multiply by the inverse projection matrix have to be normalized device coordinates, where x, y and z is in range [-1.0, 1.0]. z=-1.0 is the minimum depth (near plane) and z=1.0 is the maximum depth (far plane).

请注意,视线(视线)在视口上的投影当然是一个点.

A note, the projection of the line of sight (view ray) onto the viewport is a point, of course.

当您通过(逆)投影矩阵进行乘法运算时,结果不是笛卡尔坐标,但它是同类坐标. 您必须执行透视划分,才能将同构坐标转换为笛卡尔坐标坐标:

When you perform a multiplication by a (inverse) projection matrix, then the result is not a Cartesian coordinates, but it's a Homogeneous coordinates. You have to perform a Perspective divide to convert from Homogeneous coordinates to Cartesian coordinates:

// transform x and y mouse coordinate to normalized device space 
Vector2d mousePos = mouseInput.getCurrentPos();
float x = (float)(2 * mousePos.x) / (float)wdwWitdh - 1.0f;
float y = 1.0f - (float)(2 * mousePos.y) / (float)wdwHeight;

....

// normalized device coordinate to view space coordinate (near plane)
Vector4f tmpVec = new Vector4f();
tmpVec.set(x, y, -1.0f, 1.0f);
tmpVec.mul(invProjectionMatrix);

// perspective divide
tmpVec.x = tmpVec.x / tmpVec.w;
tmpVec.y = tmpVec.y / tmpVec.w;
tmpVec.z = tmpVec.z / tmpVec.w;
tmpVec.w = 1.0;

// normalized device coordinate to view space coordinate (far plane)
Vector4f tmpVec1 = new Vector4f();
tmpVec1.set(x, y, 1.0f, 1.0f);
tmpVec1.mul(invProjectionMatrix);

// perspective divide
tmpVec1.x = tmpVec1.x / tmpVec1.w;
tmpVec1.y = tmpVec1.y / tmpVec1.w;
tmpVec1.z = tmpVec1.z / tmpVec1.w;
tmpVec1.w = 1.0;


投影矩阵描述从场景的3D点到视口的2D点的映射.投影矩阵从视图空间转换为剪辑空间.通过除以剪辑坐标的w分量,将剪辑空间中的坐标转换为范围为(-1,-1,-1)到(1、1、1)的归一化设备坐标(NDC).

The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. The projection matrix transforms from view space to the clip space. The coordinates in the clip space are transformed to the normalized device coordinates (NDC) in the range (-1, -1, -1) to (1, 1, 1) by dividing with the w component of the clip coordinates.

在透视投影"中,投影矩阵描述了从针孔相机中看到的世界3D点到视口的2D点的映射.
摄像机视锥中的眼睛空间坐标(截断的金字塔)映射到立方体(规范化的设备坐标).

At Perspective Projection the projection matrix describes the mapping from 3D points in the world as they are seen from of a pinhole camera, to 2D points of the viewport.
The eye space coordinates in the camera frustum (a truncated pyramid) are mapped to a cube (the normalized device coordinates).

因此,视口上的xy坐标取决于深度(视图空间z坐标).

Because, of that, the x and y coordinate on the viewport depends on the depth (view space z coordinate).

这篇关于翻译为世界坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆