Question

Few days ago I decided to start in 3D programming and came across perspective projection. I use the following code to get the matrix:

public static Matrix3D ProjectionMatrix(double angle, double aspect, double near, double far)
{
    double size = near * Math.Tan(MathUtils.DegreeToRadian(angle) / 2.0);
    double left = -size, right = size, bottom = -size / aspect, top = size / aspect;
    Matrix3D m = new Matrix3D(new double[,] {
    {2*near/(right-left),0,(right + left)/(right - left),0},
    {0,2*near/(top-bottom),(top+bottom)/(top-bottom),0},
    {0,0,-(far+near)/(far-near),-(2 * far * near) / (far - near)},
    {0,0,-1,0}
    });
    return m;
}

I use the following code for the camera:

Matrix3D Camera
{
    get
    {
        Vector3D cameraZAxis = -this.LookDirection;
        cameraZAxis.Normalize();

        Vector3D cameraXAxis = Vector3D.CrossProduct(this.UpDirection, cameraZAxis);
        cameraXAxis.Normalize();

        Vector3D cameraYAxis = Vector3D.CrossProduct(cameraZAxis, cameraXAxis);

        Vector3D cameraPosition = (Vector3D)this.Position;
        double offsetX = -Vector3D.DotProduct(cameraXAxis, cameraPosition);
        double offsetY = -Vector3D.DotProduct(cameraYAxis, cameraPosition);
        double offsetZ = -Vector3D.DotProduct(cameraZAxis, cameraPosition);

        return new Matrix3D(new double[,]{{cameraXAxis.X, cameraYAxis.X, cameraZAxis.X, 0},
                            {cameraXAxis.Y, cameraYAxis.Y, cameraZAxis.Y, 0},
                            {cameraXAxis.Z, cameraYAxis.Z, cameraZAxis.Z, 0},
                            {offsetX, offsetY, offsetZ, 1}});
    }
}

However, I don't know how to get the Model or World Matrix, also is there anything wrong with the previous code?

Was it helpful?

Solution

A Matrix is used to transform an object from one "space" into another. Think of a Model which is a cube, the model center is 0,0,0 and each corner is at an extent of 5. Now to transform that into your world you would apply a Worldmatrix with the transformation to put these model coordinates into your world.

A translation for example which should "move" the model to 5, 5, 5. Now just think of adding this position to your model and all its points, and now these new coordinates are called "in world space". Now the model is, via your World matrix placed in the world at position 5,5,5 (your former model center resides now in your world at this position).

The view matrix is a little bit tricky to understand, but the easiest is to think of "We can't move a camera, so we move all ojects in the opposite direction so it looks like we moved the camera". This sounds difficult, but in fact its the same like transforming from model space to world space.

Now we transform from World space into view space. Finally, we need to get it on the screen. Obviously your screen is 2D and you still have a 3D scene, now you need a way to transform your 3D objects into your view space. This can be achieved with different kinds of projection. The two important ones are orthogonal projection and perspective projection. In fact this uses the Z component( which we don't have on a 2D surface like a screen) and the screen resolution to "project" our visible world into our screen space.

All this is easily accomplished using matrices. One for each transformation is a good start. To be fair, you don't need any of it, you could directly supply your data in screen space, but this wouldn't be practical. If you don't need a World matrix for example, which happens if your model is modeled so that it could be used directly, you would use an Matrix.Identity which, can roughly be interpreted as multiplying a number by 1 which gives you the same number. Also an Identity Matrix for the view is like having the camera placed in the world on 0,0,0 and looking down the Z axis (which axis heavly depends on the coordinate system you use)

To get the final matrix for a shader you usually pass all these matrices (or a combined one via multiplication) to your shader. If you use the fixed function pipeline there are usually methods to supply them. The projection is usually fixed, but could be changed to apply some visual effects like zooming a sniper rifle or a fisheye effect. The camera matrix of course is used to move and rotate the camera. And the world matrix is used to position your objects in the scene, move players, rotate doors etc.

Disclaimer: This is how i understood the whole thing for myself, so it is by no means a mathematical correct explanation, but maybe it is of any help for the OP.

To get a better understanding of the whole subject you can read this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top