Aaron Anodide
Aaron Anodide

Reputation: 17186

What's the difference between world and view for purpose of camera?

I'm a beginner so I'm probably confused on some fundamental level, but I seem to get the same result with the following two Draw() routines and I'm wondering is there any difference and is one more correct than the other?

In one I apply transformation to the world matrix and in the other I apply transformation to the veiw matrix. I think the result is exactly the same but I'm not 100% sure.

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

How's that different from:

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

Upvotes: 0

Views: 147

Answers (2)

Andrew Russell
Andrew Russell

Reputation: 27225

The three matrices have semantic meaning:

  • First, the World matrix moves models around the world (you have one for each object)
  • Then, the View matrix moves the entire world around - effectively this is the same as moving the camera around within the world
  • Finally, the Projection matrix takes the transformed vertices of the world and projects them into the raster space of the screen

These three matrices are multiplied in that order.

So if you multiply myWorld * myView and assigned the result into the view matrix, leaving the world as the identity matrix, the result is the exactly the same as if you had assigned myWorld into world and myView to view and let the next layer down handle the multiplication.

While the result is the same - it is generally best to stick with the semantic meanings where they are available. It makes your code more readable.

Upvotes: 2

Aki Suihkonen
Aki Suihkonen

Reputation: 20027

Matrix multiplication is associative: (A*B)C = A(B*C), but not commutative: AB != BA for every matrix. Thus, if DrawModels multiplies the matrices world, view and projection from left to right, then the two methods give exactly the same results (+- rounding errors...).

It's purely a design issue, how the matrices are decomposed or concatenated. E.g. premultiplying viewMatrix and projectionMatrix can make sense -- IIRC viewMatrix * symmetric_projectionMatrix introduces just 4 or 5 extra multiplications to the generation of the viewMatrix from 3 Euler angles or quaternion camera representation. Doing the multiplication for generic 4x4 matrices takes 64 multiplications...

One thing to consider is how to cull bounding boxes -- either axis aligned, or generic. This can be done in world space, camera space or clip space. Which ever makes most sense should dictate how the matrices are premultiplied.

Upvotes: 1

Related Questions