这是正确的视角 FOV 矩阵吗?

发布于 2024-11-08 14:35:47 字数 560 浏览 4 评论 0原文

我有一个透视视野,但旋转时,它“看起来”不正确 - 较远的物体比较近的物体移动得更快,将它们从屏幕中间经过。

那么:这是正确的吗?使用右手坐标,如果这很重要的话?

    public static Matrix4x4 PerspectiveFOV(float fov, float aspect, float near, float far)
    {
        float yScale = 1.0F / (float)Math.Tan(fov / 2);
        float xScale = yScale / aspect;
        float farmnear = far - near;
        return new Matrix4x4(
            xScale, 0, 0, 0,
            0, yScale, 0, 0,
            0, 0, far / (farmnear), 1,
            0, 0, -near * (far / (farmnear)), 1
            );
    }

谢谢。

I have a perspective FOV, but when rotating, it doesn't "look" correct - Farther objects traverse faster than closer objects, passing them in the middle of the screen.

So: Is this correct? Using right-handed coordinates, if that matters?

    public static Matrix4x4 PerspectiveFOV(float fov, float aspect, float near, float far)
    {
        float yScale = 1.0F / (float)Math.Tan(fov / 2);
        float xScale = yScale / aspect;
        float farmnear = far - near;
        return new Matrix4x4(
            xScale, 0, 0, 0,
            0, yScale, 0, 0,
            0, 0, far / (farmnear), 1,
            0, 0, -near * (far / (farmnear)), 1
            );
    }

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌生 2024-11-15 14:35:47

我看到了几个问题。
首先, tan() 的参数应从度数转换为弧度。

其次,OpenGL中透视投影的公式与你的有点不同。正如此处所指定的,它在分母中使用“近-远”而不是您的“远-近'。分子项也不同。稍微修改一下你的函数并从 Java 转换为 C,我生成了一个与 gluPerspective() 给出的投影矩阵相同的投影矩阵,其中包含以下内容:

static void my_PerspectiveFOV(double fov, double aspect, double near, double far, double* mret) {
    double D2R = M_PI / 180.0;
    double yScale = 1.0 / tan(D2R * fov / 2);
    double xScale = yScale / aspect;
    double nearmfar = near - far;
    double m[] = {
        xScale, 0, 0, 0,
        0, yScale, 0, 0,
        0, 0, (far + near) / nearmfar, -1,
        0, 0, 2*far*near / nearmfar, 0 
    };
    geom_matrix4_copy(m, mret);
}

I see a couple of problems.
First, the argument to tan() should be converted from degrees to radians.

Second, the formula for perspective projection in OpenGL is a little different from yours. As specified here, it uses 'near - far' in the denominator instead of your 'far - near'. The numerator terms are also different. Modifying your function slightly and converting from Java to C, I produced a projection matrix identical to the one given by gluPerspective() with the following:

static void my_PerspectiveFOV(double fov, double aspect, double near, double far, double* mret) {
    double D2R = M_PI / 180.0;
    double yScale = 1.0 / tan(D2R * fov / 2);
    double xScale = yScale / aspect;
    double nearmfar = near - far;
    double m[] = {
        xScale, 0, 0, 0,
        0, yScale, 0, 0,
        0, 0, (far + near) / nearmfar, -1,
        0, 0, 2*far*near / nearmfar, 0 
    };
    geom_matrix4_copy(m, mret);
}
晒暮凉 2024-11-15 14:35:47

对于诸如此类的问题,我会推荐一个很好的资源:
https://www.scratchapixel.com/课程/3d-基础渲染/透视和正交投影矩阵
它确实涉及投影矩阵的细节。它们是更多关于相机、构建相机光线等主题的课程。您需要进行一些挖掘。

For questions such as this one I would suggest an excellent resources:
https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix
It really goes in the detail of the projection matrix. They are more lessons on the topic of camera, constructing camera rays, etc. You will need to do some digging.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文