Tip
通过本文,你将了解:
- MVP变换的基本实现(作业1)
Note
Ubuntu安装OpenCV教程将在后续给出。
前言
最近在备战复试项目,感觉图形学和我比较契合,遂努力速通GAMES101,最好能把202也学一些吧。
作业1
作业要求实现get_model_matrix
与get_projection_matrix
,即实现Model矩阵与Projection矩阵。
Model矩阵实现
Model矩阵实现较为简单,直接给出:
Eigen::Matrix4f get_model_matrix(float rotation_angle){ Eigen::Matrix4f model = Eigen::Matrix4f::Identity(); model << std::cos(rotation_angle/180*std::acos(-1)), -std::sin(rotation_angle/180*std::acos(-1)), 0, 0, std::sin(rotation_angle/180*std::acos(-1)), std::cos(rotation_angle/180*std::acos(-1)), 0,0, 0,0,1,0, 0,0,0,1; return model;}
Tip
需注意,对于角度计算,我们需要将rotation_angle从弧度制转化为角度制rotation_angle/180*std::acos(-1)
。其中std::acos(-1)
=。
Projection矩阵实现
在实现Projection矩阵之前,我们先回顾一下在进行Projection有关知识点。
Projection有两种,分别为正交投影(orthogonal projection)与透视投影(prespective projection)。在实际投影过程中,如果是透视投影我们会先通过一个矩阵将透视投影变化为正交投影再按正交投影处理。
先从一般的正交投影开始讲起,它可以分为平移与缩放两步,,其中有:
需要注意的是,我们要先做平移再做放缩。
接下来是透视投影部分。上文已经讲过,对于透视投影,我们只需要将其转化为正交投影即可,因此,我们只需在右乘一个变换矩阵即可。具体推导看视频。
Warning
在OpenGL中,默认使用左手系,此时需将其改为如下形式:
在作业2中我们很快就将看到。
故,我们可以得到代码如下:
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float 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 M_proj_to_ortho, M_ortho, S_ortho, T_ortho;
M_proj_to_ortho << zNear, 0, 0, 0, 0, zNear, 0, 0, 0, 0, zNear+zFar, -zNear*zFar, 0,0,1,0;
float t,r; t = std::abs(zNear * std::tan(eye_fov/180*std::acos(-1) / 2.0f)); float b = -t; r = t * aspect_ratio; float l = -r; // S_ortho << 1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1;
S_ortho << 2.0f/(r-l),0,0,0, 0,2.0f/(t-b),0,0, 0,0,2.0f/(zNear-zFar),0, 0,0,0,1;
T_ortho << 1,0,0,-(r+l)/2, 0,1,0,-(t+b)/2, 0,0,1,-(zNear+zFar)/2.0f, 0,0,0,1;
M_ortho = S_ortho * T_ortho; projection = M_ortho * M_proj_to_ortho; return projection;}
对应完整公式:
Note
插一句题外话,课程中的思考“z是变近还是变远”,其答案是变远。
我们假设z距离不变,并计算实际的坐标,有:
对assume和real的z坐标进行联立,可得,在区间中,实际坐标大于假设(不变)。
作业1提高项部分过于简单,故不在此提供。
结语
作业1属于热身性质,别忘了概念就行。