相机变换矩阵和视图矩阵之间的确切区别是什么(使用 OpenGL 和 lwjgl)

What is the exact difference between the camera transformation matrix and the view matrix (using OpenGL and lwjgl)

问这个问题之前在网上看了很多资料,才明白View矩阵就是Camera Transformation矩阵的逆矩阵。为了清楚起见,如果我们将相机视为像场景中任何其他 3D 对象一样进行转换的实际实体(因此使用转换矩阵,首先平移,然后旋转然后缩放对象)我们获得相机转换包含相机位置的矩阵。如果我们反转这个矩阵,我们应该获得视图矩阵,但是这不是我的代码中发生的事情。我有两种静态方法:一种是在给定位置、3 个轴的旋转和一个应用于所有轴的缩放值(首先平移,然后旋转,然后缩放)的情况下创建变换矩阵,另一种创建给定相机的视图矩阵,它有一个偏航(y 轴的旋转),一个俯仰(绕 x 轴的旋转)和一个代表位置的 Vec3(在这里我们首先旋转相机然后用它的负位置平移它,因为移动相机就相当于移动它周围的世界)。这是转换矩阵的代码:

public static Matrix4f createTransformationMatrix(Vector3f translation, float rx, float ry,
        float rz, float scale) {
    
    Matrix4f matrix = new Matrix4f();
    matrix.setIdentity();
    
    Matrix4f.translate(translation, matrix, matrix);
    
    Matrix4f.rotate((float)Math.toRadians(rx), new Vector3f(1, 0, 0), matrix, matrix);
    Matrix4f.rotate((float)Math.toRadians(ry), new Vector3f(0, 1, 0), matrix, matrix);
    Matrix4f.rotate((float)Math.toRadians(rz), new Vector3f(0, 0, 1), matrix, matrix);
    
    Matrix4f.scale(new Vector3f(scale, scale, scale), matrix, matrix);
    
    return matrix;
}

下面是视图矩阵的代码:

public static Matrix4f createViewMatrix(Camera camera) {
    Matrix4f viewMatrix = new Matrix4f();
    viewMatrix.setIdentity();
    
    Matrix4f.rotate((float) Math.toRadians(camera.getPitch()), new Vector3f(1, 0, 0), viewMatrix, viewMatrix);
    Matrix4f.rotate((float) Math.toRadians(camera.getYaw()), new Vector3f(0, 1, 0), viewMatrix, viewMatrix);
    
    Vector3f cameraPos = camera.getPosition();

    Vector3f negativeCameraPos = new Vector3f(-cameraPos.x, -cameraPos.y, -cameraPos.z);
    Matrix4f.translate(negativeCameraPos, viewMatrix, viewMatrix);
    
    return viewMatrix;
}

问题来了:由于我在Youtube上学习了如何构建这两个矩阵的教程,而我并没有自己编写这段代码,所以我不明白viewMatrix是如何反转相机变换矩阵的。我注意到在 createViewMatrix() 中我们先旋转然后平移(负位置),而在 createTransformationMatrix() 中我们先平移然后旋转然后缩放。因此,如果我理解正确的话,我可以用 Camera 数据创建一个转换矩阵,然后将其反转以获得 View 矩阵,但它不起作用。我还尝试在 createViewMatrix() 中首先平移正位置(不计算负相机位置)然后旋转然后反转矩阵。同样的结果:它不起作用,当我 运行 程序时发生了奇怪的事情(我不知道如何解释它们,但它们是错误的)。我尝试了很多其他的东西,但它只适用于我提供的代码。你能解释一下吗如何先旋转然后用负相机位置平移提供倒置相机变换矩阵? 很抱歉冗长,但我希望您能在第一时间理解我的问题,以便您可以回答我。谢谢。

您对相机和视图矩阵的基本理解是正确的。相机通常用于描述viewer/camera在世界中的位置和方向,而视图矩阵将用于从世界space转换为视图space,所以它应该是相反的相机矩阵。

请注意,在矩阵数学中,应用变换的顺序有所不同:旋转然后平移与平移然后旋转不同(我们将在此处不考虑缩放等式,因为您通常不会t 缩放相机 - 缩放将通过投影矩阵完成)。

构建相机矩阵时,您首先要旋转以设置相机方向,然后平移以设置相机位置,即您将相机视为位于 0/0/0 处,沿 z 轴看(因此视图矢量将为 0/0/1)。旋转后你会得到不同的归一化视图向量,但相机仍会“坐在”0/0/0 处。然后你转换到实际的相机位置(你可能需要额外的矩阵运算来计算那个位置,但我会在一个单独的步骤中为初学者做这个 - 直到你做对了)。

Can you explain me how first rotating and then translating with the negative camera position provides the inverted camera transformation matrix please?

不应该,因为生成的视图矩阵会应用不同的方向。 “负”旋转(即角度 +/- 180 度)应该可以。在那种情况下,您旋转一个矢量以指向相机(因此,如果相机围绕 y 轴旋转 45 度,任何“指向相机”的对象都需要围绕同一轴旋转 225 或 -135 度)。

负平移是可以的,因为如果你将相机移动到世界中的 4/3/2 space -4/-3/-2 的平移将移动世界中的任何坐标 space进入视野 space.