matrixperspectivefieldofview

Is this a correct perspective FOV matrix?


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.


Solution

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