【GAMES101】Homework 1 Study Summary

This series of blogs is to record the problems and thoughts that the author encountered while studying the GAMES101 course.


1. Basic questions

From Assignment1.pdf, you can know that the task of the basic question is to fill in the two functions

  • get_model_matrix()
  • get_projection_matrix()

The other module function frameworks have already been given. You only need to carefully read the content in Assignment1.pdf and read the source code to try to understand. Affect the final job result.

Next, explain the functions that need to be filled in this question in the order of MVP.

  1. get_model_matrix() :
    Since the title requires rotation around the z-axis , the rotation matrix can be known from homework 0:
    insert image description here
    first understand the meaning of the formal parameters passed in to the function, and by observing mian()the function, we can know that rotation_anglethe rotation angle is passed in:

    Eigen::Matrix4f get_model_matrix(float rotation_angle)
    {
          
          
        Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
    
        // TODO: Implement this function
        // Create the model matrix for rotating the triangle around the Z axis.
        // Then return it.
    
        float Radian_angle = rotation_angle / 180 * MY_PI; //Radian
        Eigen::Matrix4f Rz;
        Rz << 
            cos(Radian_angle), -sin(Radian_angle), 0, 0,
            sin(Radian_angle), cos(Radian_angle), 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1;
    
        model = Rz * model;
    
        return model;
    }
    

    The float Radian_angle = rotation_angle / 180 * MY_PI;statement is because the trigonometric functions such as sin and cos in the math library use the radian system, but the input rotation_angleis the angle system, and the angle needs to be converted to radians first.

  2. get_view_matrix() :
    The working framework of this function has been given. By observing mian()the function, we can know that eye_posthe angle of view position is passed in, that is, the position of the camera. Next, briefly analyze the function of the function:

    Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eye_pos)
    {
          
          
        Eigen::Matrix4f view = Eigen::Matrix4f::Identity();
    
        Eigen::Matrix4f translate;
        translate << 1, 0, 0, -eye_pos[0], 0, 1, 0, -eye_pos[1], 0, 0, 1,
            -eye_pos[2], 0, 0, 0, 1;
    
        view = translate * view;
    
        return view;
    }
    

    The function of the view matrix is ​​actually the process of moving the camera to the standard source point. From this analysis, we can know that the translatematrix in the above code actually does such a thing, because we can know from the lecture that the translation operation is actually at the end of the fourth-order matrix One column represents the translation distance.
    insert image description here
    Since eye_posthe current position of the camera is stored in , but to translate to the source point, a parameter with a negative value must be translated, such as (1, 0, 0), if you want to translate to the source point, you must translate -1 distance on the x-axis, so by This makes it easy to understand translatethe camera translation operation done by the matrix.

  3. get_projection_matrix() :
    The last is the projection matrix. Through the analysis of Professor Yan, we can know that the projection matrix first needs to compress the image, that is, squeeze a high-resolution image into an image that can be put into the camera, and then proceed Orthogonal projection can obtain the image of distant objects projected to the camera.

    The corresponding is actually M persp → ortho M_{persp\rightarrow ortho}Mpersporthomatrix for image compression and M ortho M_{ortho}MorthoThe matrix is ​​orthographically projected. Through the analysis of Professor Yan, we can know that the two matrices are:
    M persp → ortho = ( n 0 0 0 0 n 0 0 0 0 n + f − nf 0 0 1 0 ) M_{persp\rightarrow ortho}=\left( \begin{matrix} n& 0& 0& 0\\ 0& n& 0& 0\\ 0& 0& n+f& -nf\\ 0& 0& 1& 0\\ \end{matrix} \right)Mpersportho= n0000n0000n+f100nf0
    M o r t h o = ( 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 ) ( 1 0 0 − r + l 2 0 1 0 − t + b 2 0 0 0 − n + f 2 0 0 0 1 ) M_{ortho}=\left( \begin{matrix} \frac{2}{r-l}& 0& 0& 0\\ 0& \frac{2}{t-b}& 0& 0\\ 0& 0& \frac{2}{n-f}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right) \left( \begin{matrix} 1& 0& 0& -\frac{r+l}{2}\\ 0& 1& 0& -\frac{t+b}{2}\\ 0& 0& 0& -\frac{n+f}{2}\\ 0& 0& 0& 1\\ \end{matrix} \right) Mortho= rl20000tb20000nf200001 1000010000002r+l2t+b2n+f1
    First analyze the meaning of the formal parameters of the projection matrix

    • eye_fov: is the viewing angle, which is the opening angle shown on page 30 of GAMES101_Lecture_04.pdf
    • aspect_ratio: is the aspect ratio, this title is 1, that is, the camera is square
    • zNearand zFar: are the distance from the eye to the camera and the distance from the eye to the view, corresponding to nn shown on page 30 of GAMES101_Lecture_04.pdfn andfff
    Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                          float zNear, float zFar)
    {
          
          
        zNear = -zNear;
        zFar = -zFar;
        // Students will implement this function
    
        Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
    
        // TODO: Implement this function
        // Create the projection matrix for the given parameters.
        // Then return it.
    
        Eigen::Matrix4f Mpersp_to_ortho;
        Mpersp_to_ortho << 
            zNear, 0, 0, 0,
            0, zNear, 0, 0,
            0, 0, zNear+zFar, -zNear*zFar,
            0, 0, 1, 0;
    
        float eye_fov_havle = eye_fov / 2 / 180 * MY_PI;
        float top = tan(eye_fov_havle) * -zNear; //because zNear is a nagetive number, but top is positive number
        float bottle = -top;
        float right = top * aspect_ratio;
        float left = -right;
        Eigen::Matrix4f Mortho, translation, canonical;
        translation << 
            1, 0, 0, -(right+left)/2,
            0, 1, 0, -(top+bottle)/2,
            0, 0, 1, -(zNear+zFar)/2,
            0, 0, 0, 1;
        canonical <<
            2/(right-left), 0, 0, 0,
            0, 2/(top-bottle), 0, 0,
            0, 0, 2/(zNear-zFar), 0,
            0, 0, 0, 1;
        Mortho = canonical * translation;
        projection = Mortho * Mpersp_to_ortho;
        return projection;
    }
    

    The first is the sum of the first two sentences zNear = -zNear;, zFar = -zFar;because the formula derived by Professor Yan in class is based on the fact that we are in the positive direction of the z-axis and look towards the negative direction, so the nn in the formulan andfff is a negative number, but observingmain()the function shows that when the function is called, a positive number is passed in, that is, the meaning of these two formal parameters is the distance, so we need to manually adjust it to a negative value.

    The following code is very simple, and you should be able to understand it after listening carefully in class. It corresponds to the conversion process on pages 23 and 24 of GAMES101_Lecture_04.pdf .

    Then according to the same steps of job 0, first create a new build folder in the corresponding code framework , then copy run0.sh to the build folder, and change the name to run1.sh , and follow the steps in Assignment1.pdf , Change the content of it to

    #/bin/bash
    cmake ..
    make -j4
    ./Rasterizer
    

    Execute after the modification is completed ./run1.sh, and the following results show that the operation is correct:
    insert image description here
    Press the A and D keys to rotate the triangle around the z-axis , because we are looking in the negative direction of the z-axis , so press the A key to increase the angle and the triangle should rotate counterclockwise That's right.

Two, improve the question

According to Assignment1.pdf , it can be seen that the improvement question needs to construct get_rotation()a function to realize the rotation around any axis. The Rodrigues' Rotation Formula
mentioned by Professor Yan in the class can realize this function, which is located on page 10 of the courseware GAMES101_Lecture_04.pdf , but to be honest, I did not understand the principle of this formula, but realized the function according to the gourd painting, and did not To know whether the answer is correct, dig a hole first, and fill it in later when you have time [doge.jpg].get_rotation()

Here I recommend 剑 来!a blog . Chapter 2.2 is about the formula for rotating around any axis in three dimensions. It is easy to understand, but it is inconsistent with the Rodrigue rotation formula taught by Professor Yan. It can be used as a supplement Materials to read.

Eigen::Matrix4f get_rotation(Vector3f axis, float angle)
{
    
    
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();

    // TODO: Implement this function
    // Create the model matrix for rotating the triangle around the Z axis.
    // Then return it.

    float Radian_angle = rotation_angle / 180 * MY_PI; //Radian

    Eigen::Matrix4f I, N, Rod;
    Eigen::Vector4f n(axis.x(), axis.y(), axis.z(), 0);
    Eigen::RowVector4f nT(axis.x(), axis.y(), axis.z(), 0);
    I <<
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;
    N <<
        0, -axis.z(), axis.y(), 0,
        axis.z(), 0, -axis.x(), 0,
        -axis.y(), axis.x(), 0, 0,
        0, 0, 0, 1;

    Rod = cos(Radian_angle) * I + (1 - cos(Radian_angle)) * n * nT + sin(Radian_angle) * N;
    Rod(3, 3) = 1; //Ensure correct proportion

    return Rod;
}

Guess you like

Origin blog.csdn.net/qq_21891843/article/details/130654799