1. 透视投影矩阵推导
a. 将物体投射到我们的眼睛里需要经过一些变换。
a>正交投影 (Orthographic projection)
将物体中心先移动到坐标原点,然后缩放为(-1 ~ 1)1^3内的立方体中。
b>透视投影 (Perspective projection)
跟着闫老师推导了一遍,思路清晰:
- 首先有个性质,(1, 0, 0, 1) and (2, 0, 0, 2) both represent (1, 0, 0)
- 如何将远平面上的点变换到近平面上。
- 上图由远近平面的位置,计算出x -> x′ 、y -> y ′ 的比例值,由此可计算出x,y上的变化量。
- 如何计算第三行值呢?用到透视投影里我们发现:
在近平面的任意一个点经过变换后位置不变,
在远平面上的任意一个点经过变换后z轴的位置不变性,
得出以下推导:
5.然后接着算出第三行的值
外附上第一次作业代码:
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;
}
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 angle = rotation_angle / 180 * MY_PI;
Eigen::Matrix4f rotation;
rotation << cos(angle), -sin(angle), 0, 0,
sin(angle), cos(angle), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
model = rotation * model;
return model;
}
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
float zNear, float zFar)
{
//aspect_ratio 高宽比
// eye_fov 可视角度
// Students will implement this function
// TODO: Implement this function
// Create the projection matrix for the given parameters.
// Then return it
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
Eigen::Matrix4f Mortho;
double angle = eye_fov * MY_PI / 180;
double n = zNear;
double f = zFar;
double t = abs(n) * tan(angle / 2);
double b = -t;
double r = t * aspect_ratio;
double l = -r;
Eigen::Matrix4f Mtranstale;
Mtranstale << 1, 0, 0, -(l + r) / 2,
0, 1, 0, -(t + b) / 2,
0, 0, 1, -(n + f) / 2,
0, 0, 0, 1;
Eigen::Matrix4f Mscale;
Mscale << 2 /(r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, 2 / (n - f), 0,
0, 0, 0, 1;
Mortho = Mscale * Mtranstale;
Eigen::Matrix4f Mpersp_ortho;
Mpersp_ortho << n,0, 0, 0,
0, n, 0, 0,
0, 0, n+ f, -(n* f),
0, 0, 1, 0;
projection = Mortho * Mpersp_ortho;
return projection;
}
注意:部分同学会出现三角形上下颠倒问题,这是因为文中所讲的远近平面都为负值,代码中传入的值为正值。
自此全剧终