为了相机的目的,世界和景观有什么区别?

时间:2012-10-29 20:13:49

标签: xna-4.0

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

在一个实例中,我将转换应用于世界矩阵,另一个应用转换到veiw矩阵。我认为结果完全相同,但我不是百分百肯定。

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

2 个答案:

答案 0 :(得分:2)

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

  • 首先, World 矩阵在全球范围内移动模型(每个对象都有一个)
  • 然后,视图矩阵移动整个世界 - 实际上这与在世界范围内移动相机相同
  • 最后, Projection 矩阵获取世界的变换顶点并将它们投影到屏幕的栅格空间

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

因此,如果您将myWorld * myViewview矩阵相乘并将结果分配到world矩阵,将myWorld保留为单位矩阵,则结果与您指定的结果完全相同{ {1}}进入worldmyViewview,让下一层向下处理乘法。

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

答案 1 :(得分:1)

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

这纯粹是一个设计问题,矩阵如何被分解或连接。例如。预乘视图矩阵和投影矩阵可以有意义 - IIRC viewMatrix * symmetric_projectionMatrix从3个欧拉角或四元数相机表示中生成viewMatrix仅引入4或5次额外乘法。对通用4x4矩阵进行乘法需要64次乘法...

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