0

私は初心者なので、基本的なレベルで混乱している可能性がありますが、次の 2 つの Draw() ルーチンで同じ結果が得られるようで、違いはあるのでしょうか?

1 つはワールド マトリックスに変換を適用し、もう 1 つはビュー マトリックスに変換を適用します。結果はまったく同じだと思いますが、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

3 つの行列には意味的な意味があります。

  • まず、Worldマトリックスがモデルを世界中に移動します (オブジェクトごとに 1 つ)。
  • 次に、ビューマトリックスがワールド全体を移動します。これは、事実上、ワールド内でカメラを移動するのと同じです。
  • 最後に、Projectionマトリックスはワールドの変換された頂点を取得し、それらを画面のラスター空間に投影します。

これら 3 つの行列は、この順序で乗算されます。

したがって、乗算myWorld * myViewして結果をview行列に代入し、 を単位行列のままにすると、結果は、におよびに代入して次の層に乗算を処理させたworld場合とまったく同じになります。myWorldworldmyViewview

結果は同じですが、一般的には、意味が利用可能な意味に固執するのが最善です。コードが読みやすくなります。

于 2012-10-30T12:38:26.547 に答える
1

行列の乗算は結合的です: (A*B) C = A (B*C) ですが、可換ではありません: AB != すべての行列の BA。したがって、DrawModels が行列のワールド、ビュー、および射影を左から右に乗算すると、2 つのメソッドはまったく同じ結果になります (+- 丸め誤差...)。

行列がどのように分解または連結されるかは、純粋に設計上の問題です。たとえば、viewMatrix と projectMatrix の事前乗算は理にかなっています -- IIRC viewMatrix * symmetric_projectionMatrix は、3 つのオイラー角またはクォータニオン カメラ表現からの viewMatrix の生成に 4 つまたは 5 つの余分な乗算を導入します。一般的な 4x4 行列の乗算を行うには、64 回の乗算が必要です...

考慮すべきことの 1 つは、バウンディング ボックスをカリングする方法です。これは、ワールド空間、カメラ空間、またはクリップ空間で行うことができます。どちらが最も理にかなっているかは、行列がどのように事前に乗算されるかを決定する必要があります。

于 2012-10-29T20:39:20.980 に答える