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);
}
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 4×4 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.