相机原点在投影矩阵中可见

camera origin is visible with projection matrix

在上图中,我显示了将相机定位 与鼠标覆盖的顶点相同的位置 的结果。类似的结果来自使用正交矩阵。我的问题是,当旋转相机时,它会围绕相机的可见原点旋转。我想要的是让视图像普通 FPS 相机一样旋转。

我认为有用的信息:

这最后一点对我来说在数学上对正交投影有意义,但是,由于近裁剪平面应该稍微在相机前面,我希望鼠标附近的点被裁剪。我知道它没有被剪裁,因为如果我旋转相机俯视立方体(不平移它),剪裁平面会在立方体垂直边缘的大约一半处切断。

我认为我的困惑可能是由于对透视投影矩阵的数学原理存在根本性误解,但这也可能是由于我的代码所致,所以让我把它包括在内:

static inline constexpr auto ortho(T l, T r, T b, T t, T n, T f) {
    return Matrix4x4{{(T)2 / (r - l), 0, 0, 0},
                     {0, (T)2 / (t - b), 0, 0},
                     {0, 0, (T)2 / (n - f), 0},
                     {(l + r) / (l - r), (b + t) / (b - t), (f + n) / (n - f), 1}};
}
static inline constexpr auto perspective(T fov, T aspect, T near, T far) {
    const T q = (T)1.0 / std::tan(0.5 * fov), 
            a = q * aspect, 
            b = (near + far) / (near - far), 
            c = near * far * 2 / (near - far);
    return Matrix4x4{
        {q, 0, 0, 0},
        {0, a, 0, 0},
        {0, 0, b, -1},
        {0, 0, c, 1},
    };
}

如果有人需要有关正在发生的事情的额外信息,请在评论中告诉我,我们很乐意回答或补充问题

阅读评论中提供的 link 并将我的方法与我编写的代码进行比较后,我意识到我在将数学转录到代码中时犯了一个错误。我不小心在透视矩阵的最后一列的最后一行放了一个1,而它应该是一个0.

此处显示更正后的代码:

static inline constexpr auto perspective(T fov, T aspect, T near, T far) {
    const T q = (T)1.0 / std::tan(0.5 * fov), 
            a = q * aspect, 
            b = (near + far) / (near - far), 
            c = near * far * 2 / (near - far);
    return Matrix4x4{
        {q, 0, 0, 0},
        {0, a, 0, 0},
        {0, 0, b, -1},
        {0, 0, c, 0},
    };
}