0

我是一个初学者,所以我可能在某些基本层面上感到困惑,但我似乎用以下两个 Draw() 例程得到了相同的结果,我想知道有什么区别,一个比另一个更正确吗?

在一个中,我将变换应用于世界矩阵,在另一个中,我将变换应用于 veiw 矩阵。我认为结果完全一样,但我不是 100% 确定。

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        Matrix worldMatrix =
            Matrix.CreateTranslation(view.Position.X, view.Position.Y, view.Position.Z) *
            Matrix.CreateRotationX(view.Rotation.X) *
            Matrix.CreateRotationY(view.Rotation.Y) *
            Matrix.CreateRotationZ(view.Rotation.Z);

        Matrix viewMatrix = Matrix.CreateLookAt(view.CameraPosition, view.CameraTarget, view.CameraUp);

        Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(view.FieldOfView,
                                                                      GraphicsDevice.Viewport.AspectRatio,
                                                                      view.NearPlane,
                                                                      view.FarPlane);

        DrawModels(worldMatrix, viewMatrix, projectionMatrix);

        base.Draw(gameTime);
    }

这与以下有何不同:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        Matrix worldMatrix = Matrix.Identity;

        Matrix viewMatrix =
            Matrix.CreateTranslation(view.Position.X, view.Position.Y, view.Position.Z) *
            Matrix.CreateRotationX(view.Rotation.X) *
            Matrix.CreateRotationY(view.Rotation.Y) *
            Matrix.CreateRotationZ(view.Rotation.Z) *
            Matrix.CreateLookAt(view.CameraPosition, view.CameraTarget, view.CameraUp);

        Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(view.FieldOfView,
                                                                      GraphicsDevice.Viewport.AspectRatio,
                                                                      view.NearPlane,
                                                                      view.FarPlane);

        DrawModels(worldMatrix, viewMatrix, projectionMatrix);

        base.Draw(gameTime);
    }
4

2 回答 2

2

这三个矩阵具有语义含义:

  • 首先,世界矩阵在世界各地移动模型(每个对象都有一个)
  • 然后,视图矩阵移动整个世界 - 实际上这与在世界内移动相机相同
  • 最后,Projection矩阵将变换后的世界顶点投影到屏幕的光栅空间中

这三个矩阵按此顺序相乘。

因此,如果您将myWorld * myView结果相乘并将其分配到view矩阵中,将 保留为单位矩阵,则结果与您分配到和到并让下一层处理乘法world时的结果完全相同。myWorldworldmyViewview

虽然结果是相同的 - 通常最好坚持可用的语义含义。它使您的代码更具可读性。

于 2012-10-30T12:38:26.547 回答
1

矩阵乘法是关联的:(A*B) C = A (B*C),但不可交换:AB != BA 对于每个矩阵。因此,如果 DrawModels 从左到右将矩阵世界、视图和投影相乘,那么这两种方法给出完全相同的结果(+- 舍入误差...)。

这纯粹是一个设计问题,矩阵是如何分解或连接的。例如,预乘 viewMatrix 和 projectionMatrix 是有意义的——IIRC viewMatrix * symmetric_projectionMatrix 只引入了 4 或 5 个额外的乘法来从 3 个欧拉角或四元数相机表示生成 viewMatrix。对通用 4x4 矩阵进行乘法运算需要 64 次乘法...

要考虑的一件事是如何剔除边界框——轴对齐或通用。这可以在世界空间、相机空间或剪辑空间中完成。哪个最有意义应该决定矩阵是如何预乘的。

于 2012-10-29T20:39:20.980 回答