截锥体剔除的截头体不是正确的

时间:2018-04-30 17:41:14

标签: java frustum

简介

我正在尝试实现视锥体剔除,为此我创建了一个projectionViewMatrix,然后使用矩阵转换向量。然而,一些矢量似乎被错误地计算出来。 (坐标系:+ x向右,+ y向上,+ z在屏幕外

代码:

public static void updateFrustum(Camera camera) {
    Vector3f[] points = calculateFrustumVertices(camera);
    plane[0].setPlane(points[1], points[0], points[2]);
    plane[1].setPlane(points[4], points[5], points[7]);
    plane[2].setPlane(points[0], points[4], points[3]);
    plane[3].setPlane(points[5], points[1], points[6]);
    plane[4].setPlane(points[2], points[3], points[6]);
    plane[5].setPlane(points[4], points[0], points[1]);
}

private static Vector3f[] calculateFrustumVertices(Camera camera) {
    // projectionMatrix was saved once at the beginning
    Matrix4f inverseProjView = Matrix4f.mul(projectionMatrix, Maths.createViewMatrix(camera), null);
    inverseProjView.invert();
    Vector3f[] points = new Vector3f[8];
    Vector4f vertex = new Vector4f();
    vertex.w = 1;

    for (int i = 0; i < 8; i++) {
        vertex.x = clipCube[i].x;
        vertex.y = clipCube[i].y;
        vertex.z = clipCube[i].z;
        Matrix4f.transform(inverseProjView, vertex, vertex);
        vertex.x /= vertex.w;
        vertex.y /= vertex.w;
        vertex.z /= vertex.w;
        vertex.w /= vertex.w;
        points[i] = new Vector3f(vertex);
    }
    return points;
}

static Matrix4f viewMatrix = new Matrix4f();
public static Matrix4f createViewMatrix(Camera camera) {
    viewMatrix.setIdentity();
    Matrix4f.rotate((float) Math.toRadians(camera.getPitch()), Maths.xRotation, viewMatrix, viewMatrix);
    Matrix4f.rotate((float) Math.toRadians(camera.getYaw()), Maths.yRotation, viewMatrix, viewMatrix);
    Matrix4f.rotate((float) Math.toRadians(camera.getRoll()), Maths.zRotation, viewMatrix, viewMatrix);
    Maths.reusableVector = camera.getPosition();
    Maths.reusableVector2.set(-Maths.reusableVector.x, -Maths.reusableVector.y, -Maths.reusableVector.z);
    Matrix4f.translate(Maths.reusableVector2, viewMatrix, viewMatrix);
    return viewMatrix;
}

示例输出:

为此我站在原点(0, 0, 0)并朝+ z方向看。我的近处飞机是0.001,我的远处飞机是1000,而FOV是60°。结果是(打印出calculateFrustumVertices()中for循环中的每个点):

  • points[0] = (0, 0, 0)
  • points[1] = (0, 0, 0)
  • points[2] = (0, 0, 0)
  • points[3] = (0, 0, 0)
  • points[4] = (1127, -591, 1110)
  • points[5] = (-1114, -591, 1110)
  • points[6] = (-1114, 668, 1110)
  • points[7] = (1127, 668, 1110)

请注意,前四个点并不完全相同,但由于近平面距离非常小(0.001),它们几乎等于零。我放弃了小数位(因为它们是无用的)。

问题:

截头体的形状大致正确。但在我看来,这些观点有点不对。

  1. 如果原点位于(0, 0, 0),则坐标不应该是 对称的?因此,例如,如果第4点和第7点的x值等于1127, 那么第5点和第6点的值不应该等于-1127? (y和z相同)。
  2. Here is a sketch for clarification)如果FOV为60°且远平面距离为1000.那么在我看来,z值应该等于![zOffset/farPlaneDist=cos(30°)](https://latex.codecogs.com/gif.latex?%5Cfrac%7BzOffset%7D%7BfarPlaneDistance%7D%20%3D%20cos%2830%B0%29%20%5CLeftrightarrow%20zOffset%20%3D%20farPlaneDistance%20%5Ccdot%20cos%2830%29)(我不被允许发布链接,sry。也许有人可以编辑帖子并摆脱“`”,这样它就是一个链接而不是代码块。谢谢!)

    如果你计算它,你会得到zOffset = 866。这比我在程序中获得的值小约300个单位。

  3. 问题:

    计算积分时我做错了什么?基本形式是相同的,但要点仍然不同于它们应该是什么。我某处有错吗?如果您需要更多信息,请说明,然后我会提供。

0 个答案:

没有答案