记录111
1 总览
到目前为止,我们已经学习了如何使用矩阵变换来排列二维或三维空间中的
对象。所以现在是时候通过实现一些简单的变换矩阵来获得一些实际经验了。在接下来的三次作业中,我们将要求你去模拟一个基于CPU 的光栅化渲染器的简化版本。
本次作业的任务是填写一个旋转矩阵和一个透视投影矩阵。给定三维下三个
点v0(2.0, 0.0,−2.0), v1(0.0, 2.0,−2.0), v2(−2.0, 0.0,−2.0), 你需要将这三个点的坐标变换为屏幕坐标并在屏幕上绘制出对应的线框三角形(在代码框架中,我们已经提供了draw_triangle 函数,所以你只需要去构建变换矩阵即可)。简而言之,我们需要进行模型、视图、投影、视口等变换来将三角形显示在屏幕上。在提供的代码框架中,我们留下了模型变换和投影变换的部分给你去完成。
如果你对上述概念有任何不清楚或疑问,请复习课堂笔记或询问助教。
以下是你需要在main.cpp 中修改的函数(请不要修改任何的函数名和其他
已经填写好的函数,并保证提交的代码是已经完成且能运行的):
• get_model_matrix(float rotation_angle): 逐个元素地构建模型变换矩
阵并返回该矩阵。在此函数中,你只需要实现三维中绕z 轴旋转的变换矩阵,而不用处理平移与缩放。
• get_projection_matrix(float eye_fov, float aspect_ratio, float
zNear, float zFar): 使用给定的参数逐个元素地构建透视投影矩阵并返回
该矩阵。
• [Optional] main(): 自行补充你所需的其他操作。
1 get_model_matrix(float rotation_angle):
Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
// TODO: Implement this function
// Create the model matrix for rotating the triangle around the Z axis.
// Then return it.
rotation_angle = rotation_angle / 180 * M_PI;
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
Eigen::Matrix4f translate;
translate << cos(rotation_angle), -sin(rotation_angle), 0, 0,
sin(rotation_angle), cos(rotation_angle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
model = translate * model;
return model;
}
2 get_projection_matrix(float eye_fov, float aspect_ratio, float
zNear, float zFar)
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
float zNear, float zFar)
{
// TODO: Implement this function
// Create the projection matrix for the given parameters.
// Then return it.
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
eye_fov = eye_fov / 180 * M_PI;
Eigen::Matrix4f M1;
M1 << zNear, 0, 0, 0,
0, zNear, 0, 0,
0, 0, zNear + zFar, -zNear * zFar,
0, 0, 1, 0;
float t = zNear * tan(eye_fov / 2);
float b = -t;
float r = t * aspect_ratio;
float l = -r;
Eigen::Matrix4f M2;
M2 << 1, 0, 0, -(r + l) / 2,
0, 1, 0, -(t + b) / 2,
0, 0, 1, -(zNear + zFar) / 2,
0, 0, 0, 1;
Eigen::Matrix4f M3;
M3 << 2 / (r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, 2 / (zNear - zFar), 0,
0, 0, 0, 1;
projection = M3 * M2 * M1;
return projection;
}