这次作业要完成两个功能:
- 判断像素中心点是否在三角形内。
只要验证顶点在三角形三条边同一侧即可,在下图中,只要ap,cp,bp在AC,CB,BA左侧,也就是叉乘结果在-Z轴即表示在三角形内。
注意:函数形参x,y要改成浮点数类型,否则MSAA无效(传入的采样点舍入后都变为一个点了)。
- 使用AABB方法光栅化三角形。
思路是这样的:
1) 确定包围盒左右上下边界
2)遍历包围盒内像素点,检查每个像素点是否在三角形内。
3) 如果在三角形内。则通过重心坐标计算对应的插值深度值,与深度缓冲区的值进行比较。
4)如果当前点更靠近相机(深度值更小),则设置像素颜色并更新深度缓冲区对应的值。
实现过程中要注意的点
1) 确定包围盒的时候左、上边界向下取整,右、下边界向上取整,保证能包住三角形。
2) MSAA中根据一个像素内采样点在三角形的比例决定颜色,在三角形中采样点/总采样点,总采样点要写成xx.0的浮点数形式,否则默认得到一个舍入的整数,MSAA无效。
Eigen::Vector3f color = t.getColor() * (count / 4.0);
3)实现过程中可能会遇到三角形颠倒的问题,如下图:
原因在于main函数中传给get_projection_matrix()的zNear和zFar是正数,我们相机是朝向负z轴的,导致结果关于原点中心对称了。。。 需要把zNear和zFar改为负值传参,如果这样还没解决问题,再看看你的的get_projection_matrix()函数FovY求高的时候是否还把zNear当成正数?公式需要的是zNear绝对值,而我们传入的是负数。 修改后,得到正确结果。
float top = tan(radian) * -zNear;
实现代码
static bool insideTriangle()
函数:
static bool insideTriangle(float x, float y, const Vector3f* _v)
{
// TODO : Implement this function to check i`在这里插入代码片`f the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
Vector2f a = _v[0].head(2) - _v[1].head(2);
Vector2f b = _v[1].head(2) - _v[2].head(2);
Vector2f c = _v[2].head(2) - _v[0].head(2);
Vector2f ap{
x - _v[0][0], y - _v[0][1] };
Vector2f bp{
x - _v[1][0], y - _v[1][1] };
Vector2f cp{
x - _v[2][0], y - _v[2][1] };
return c[0] * ap[1] - c[1] * ap[0] < 0 && a[0] * bp[1] - a[1] * bp[0] < 0 && b[0] * cp[1] - b[1] * cp[0] < 0;
}
rasterize_triangle()
函数: