1

我在 Java 中复制了gluPerspective,但是当我将结果矩阵应用于向量时,输出 z 永远不会超过 0.5(除了一点点浮点错误)。但是,它应该在 0 (-z = zNear) 和 1 (-z = zFar) 之间

是否在某处对该功能进行了单元测试,以便我可以测试我的实现是否与特定输入的已知正确输出相匹配?或者这个问题是基于错误的假设,z 介于 0 和 0.5 之间是否可以?

或者,你能发现错误吗?

/**
 * @param fov the vertical viewing angle. This is the angle, in degrees, from the top of the screen to the bottom.
 * @param aspect The aspect ratio, which controls the horizontal viewing angle relative to the vertical. We could imagine a variable fovx = aspect × fovy. For a non-stretched perspective, aspect should be the ratio of the screen width to height. For example, on a 640×480 display, aspect should be 4/3.
 * @param near The inverted z coordinate of the near clipping plane.
 * @param far The inverted z coordinate of the far clipping plane.
 */
public static Matrix4d create(double fov, double aspect, double near, double far) {

    Preconditions.checkArgument(near > 0);
    Preconditions.checkArgument(far > 0);
    Preconditions.checkArgument(far < Double.POSITIVE_INFINITY);

    double top = near * Math.tan(fov * Math.PI / 360.0);
    double right = top * aspect;
    double left = -right;
    double bottom = -top;

    return Matrix4d.create(
            (2.0 * near) / (right - left),    0,                                 0,                                      0,
            0,                                (2.0 * near) / (top - bottom),     0,                                      0,
            (right + left) / (right - left),  (top + bottom) / (top - bottom),   (-far - near) / (far - near),           -1.0,
            0,                                0,                                 (-(2.0 * near) * far) / (far - near),   0
    );

}

根据要求,这是我的矩阵向量乘法代码:

public Vector3d multiplied(Vector3d other) {

    final double r[] = new double[4]; // x, y, z, w

    for (int lRow = 0; lRow < 4; lRow++) {

        // calculate the dot product of the left row and the right vector
        double dp =
                (this.get(0, lRow) * other.x) +
                (this.get(1, lRow) * other.y) +
                (this.get(2, lRow) * other.z) +
                (this.get(3, lRow) * 1);

        r[lRow] = dp;

    }

    final double w = r[3];
    if (w != 1) {
        for (int i = 0; i < 3; i++) {
            r[i] = r[i] / w;
        }
    }

    return new Vector3d(r[0], r[1], r[2]);

}

以下是一些数字:

fov 90, aspect 1.7777777777777777, near 1, far 1000
perspective:
0.5625000000000001, 0.0, 0.0, 0.0
0.0, 1.0000000000000002, 0.0, 0.0
0.0, 0.0, -1.002002002002002, -1.0
0.0, 0.0, -2.002002002002002, 0.0

IN                                                OUT                                               
outside clipping area
[0.0, 0.0, 0.0]                                   [NaN, NaN, -Infinity]                             
[0.0, 0.0, -0.5]                                  [0.0, 0.0, -0.4985]                               
[0.0, 0.0, -2000.0]                               [0.0, 0.0, 0.5002502499999999]                    
on clipping edges
[0.0, 0.0, -1.0]                                  [0.0, 0.0, 9.999999999999775E-4]                  
[0.0, 0.0, -1000.0]                               [0.0, 0.0, 0.5000005]                             
centered
[0.0, 0.0, -2.0]                                  [0.0, 0.0, 0.25075]                               
[0.0, 0.0, -4.0]                                  [0.0, 0.0, 0.37562499999999993]                   
[0.0, 0.0, -20.0]                                 [0.0, 0.0, 0.475525]                              
[0.0, 0.0, -40.0]                                 [0.0, 0.0, 0.4880125]                             
[0.0, 0.0, -80.0]                                 [0.0, 0.0, 0.49425625]                            
to the right
[100.0, 0.0, -20.0]                               [1.4048437500000004, 0.0, 0.475525]               
[100.0, 0.0, -40.0]                               [0.7024218750000002, 0.0, 0.4880125]              
to the left
[-100.0, 0.0, -20.0]                              [-1.4048437500000004, 0.0, 0.475525]              
[-100.0, 0.0, -40.0]                              [-0.7024218750000002, 0.0, 0.4880125]             
1 to the top
[0.0, -10.0, -10.0]                               [0.0, -0.4995000000000001, 0.45055]  
4

0 回答 0