GAMES101-现代计算机图形学学习笔记(作业02)
原课程视频链接以及官网
b站视频链接: link.
课程官网链接: link.
作业
作业描述
在上次作业中,虽然我们在屏幕上画出一个线框三角形,但这看起来并不是 那么的有趣。所以这一次我们继续推进一步——在屏幕上画出一个实心三角形, 换言之,栅格化一个三角形。上一次作业中,在视口变化之后,我们调用了函数 rasterize_wireframe(const Triangle& t)。但这一次,你需要自己填写并调用函数 rasterize_triangle(const Triangle& t)。
提高篇:用 super-sampling 处理 Anti-aliasing : 你可能会注意到,当我们放大图像时,图像边缘会有锯齿感。我们可以用 super-sampling 来解决这个问题,即对每个像素进行 2 * 2 采样,并比较前后的结果 (这里 并不需要考虑像素与像素间的样本复用)。需要注意的点有,对于像素内的每一个样本都需要维护它自己的深度值,即每一个像素都需要维护一个 sample list。最后,如果你实现正确的话,你得到的三角形不应该有不正常的黑边。
需要补充的函数
rasterize_triangle(): 执行三角形栅格化算法
static bool insideTriangle(): 测试点是否在三角形内。你可以修改此函 数的定义,这意味着,你可以按照自己的方式更新返回类型或函数参数。
思路
①三角形栅格算法
作业要求已经给出了*rasterize_triangle()*函数的工作流程:
- 创建三角形的 2 维 bounding box。
- 遍历此 bounding box 内的所有像素(使用其整数索引)。然后,使用像素中心的屏幕空间坐标来检查中心点是否在三角形内。
- 如果在内部,则将其位置处的插值深度值 (interpolated depth value) 与深度 缓冲区 (depth buffer) 中的相应值进行比较。
- 如果当前点更靠近相机,请设置像素颜色并更新深度缓冲区 (depth buffer)。
老师这里要求实现的是Barycentric Algorithm(三角形栅格化),下面几个点可能需要注意一下:
①寻找三角形的bounding box:根据三角形的三个坐标,找出最大x,最小x,最大y,最小y坐标即可,注意最小x,y坐标需要取比原数小,最大x,y坐标需要取比原数大
②点是否在三角形内:只需要连接点和三角形个点,形成一系列向量,然后判断它们的叉乘结果的z值是否统一即可
③MSAA 4X 深度:把一个点看成一个格子,判断里面4个小点是否落在三角形内,然后找到其中插值的最小z值,和帧缓冲中的z值进行比较替换即可。
③MSAA 4X 颜色:
判断有4个小点中有几个小点落入三角形,然后按比例对颜色进行采样即可。
光栅化函数:
//Screen space rasterization
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
auto v = t.toVector4();
// bounding box
float min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));
float max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));
float min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));
float max_y = std::max(v[0][1], std::max(v[1][1], v[2