【GAMES101】学习记录2-Rasterization

前言

终于又有空余时间来整理了,这里整理出GAMES101-Lecture-05到07的内容。如有错误,欢迎斧正。

GAMES101教程视频传送门

记录

光栅化

光栅化是把顶点数据(一般为三角形)转化为片元显示出来的过程。
通俗地讲,就是把若干小三角形通过屏幕像素画出来的过程。

点与三角形的位置关系

最重要的问题是:如何判断某一点位于三角形内。
在图形学中,一个被广泛采用的方法是:判断三组特定向量叉乘的结果是否同号。相同则在内,不同则在外。如下。
image

static bool insideTriangle(float x, float y, const Vector3f* _v)
{   
	// TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]

	Vector2f AB = _v[1].head(2) - _v[0].head(2);
	Vector2f BC = _v[2].head(2) - _v[1].head(2);
	Vector2f CA = _v[0].head(2) - _v[2].head(2);

	Vector2f p(x , y);

	Vector2f AP = p - _v[0].head(2);
	Vector2f BP = p - _v[1].head(2);
	Vector2f CP = p - _v[2].head(2);

	return 
		AB.x() * AP.y() - AB.y() * AP.x() > 0 && 
		BC.x() * BP.y() - BC.y() * BP.x() > 0 && 
		CA.x() * CP.y() - CA.y() * CP.x() > 0;//已规定ABC三点逆时针排列
}

实际过程中,我们无需遍历所有的屏幕像素,逐个判断它们是否在三角形内。
这里有更优的解决办法来减小运算量:计算三角形的包围盒,逐个判断包围盒中的像素是否在三角形内。如下图。
image
而对于某些斜向的细长三角形,它的包围盒会很大,运算量也相应增大。
另一种优化方案是增量三角形遍历法,它可以很好地解决上述问题。如下图。
image

反走样优化方案

由于屏幕像素是一个个小方格,所以在光栅化过程中,在三角形的边缘难免会产生锯齿,这就是走样。
我们预期得到的一条平滑的三角形边,所以要对现有方案进行优化。
一般方案的优化方案有MSAA/FXAA/TAA,这里深入了解MSAA方案。

MSAA,即多重采样抗锯齿。
基本原理是:在某一个像素中增加采样点,按照处在三角形内的采样点数量,来对该像素点的颜色做平均,以减弱边缘锯齿。如下图。
image
image
image

处理深度问题

在GAMES101学习记录1中,我们暂时忽略掉模型的z轴深度问题,这里我们着手解决它。
三维空间中的物体根据z轴的纵深,具有遮挡关系。有一种渲染方法是画家算法,如同画家作油画一般,先渲染离镜头最远的,然后依次渲染离镜头越来越近的物体。但画家算法无法应对如下情况。
image

z轴缓冲区算法(z-buffer)可以很好地解决这个问题。算法思想大致为:

  1. 首先建立z-buffer二维数组,对应映射到每个屏幕像素,并初始化为最大或最小值(根据参考系与镜头位置决定)。
  2. 然后遍历模型中的每个点,若当前点在z轴上离镜头更近,则在z-buffer中的对应位置存入它,并对应修改颜色缓冲区的值。
    image

参考资料

以上笔记(含图片)总结自GAMES101课程及其PPT讲义。
GAMES101教程视频传送门

posted @ 2022-06-04 16:24  AshScops  阅读(70)  评论(0编辑  收藏  举报