Perspective Projection
下图灰色平面为近平面,由 ( l , r , b , t ) (l,r,b,t) (l,r,b,t)表示,平面对称,中心点位于Z轴上。
- Aspect ratio = width / height
近平面的宽高比,如屏幕的4:3,16:9等 - vertical field-of-view(for Y):垂直可视角度。下图两红线之间的角度。
侧面来看如下图,两个量的计算可由公式得。
Canonical Cube to Screen
屏幕就是像素的数组,数组大小表示分辨率。
raster是德语中的屏幕,rasterize意为drawing onto the screen。
屏幕空间
屏幕空间原点位于左下角,坐标为(0,0),每个像素坐标值(x,y)为整数。每个像素其实是一个小方框,像素中心点是(x+0.5,y+0.5)。屏幕范围是(0,0) - (width, height)。
将立方体变换到屏幕空间
- 将立方体的x和y方向拉伸到和屏幕一样的aspect ratio,即将 [ − 1 , 1 ] 2 [−1,1]^2 [−1,1]2 转化为 [ 0 , w i d t h ] × [ 0 , h e i g h t ] [0, width ]×[0, height] [0,width]×[0,height]。应该对立方体先除以2,再乘width或height。
- 拉伸前后立方体中心点在屏幕原点,应该把中心点移到屏幕中心点
(
w
i
d
t
h
/
2
,
h
e
i
g
h
t
/
2
)
(width/2, height/2)
(width/2,height/2)。
则视口变换(viewport transform)矩阵为:
光栅化
光栅化是将向量图形格式表示的图像转换成位图以用于显示器或者打印机输出的过程。将连续的图像变为离散的像素。
三角形是基本的图元,也是最基本的多边形,可以构成很多复杂的mesh。
其特性:
- Guaranteed to be planar (保证是平面的)
- well-defined interior(判断一个点在不在三角形内非常方便)
- Well-defined method for interpolating values at vertices over triangle (barycentric interpolation,重心插值)
经过视口变换后得到下图右边的情况,三角形的坐标是小数,有些地方只占了像素格很小的部分,那么该像素是否亮呢。应该判断像素和三角形的关系决定该像素是否亮。
判断像素点与三角形关系
通过采样来判断。
定义一个函数f(x),遍历每个点,根据与函数f(x)计算结果来判断位置关系,即通过采样对函数进行离散化处理。
for (int x = 0; x < xmax; ++x)
for (int y = 0; y < ymax; ++y)
image[x][y] = inside(tri, x + 0.5, y + 0.5);
inside函数可以通过叉乘来实现,三边叉乘得到的向量方向一致则点在三角形内。P点使用的是像素的中心点。通过遍历所有像素点,即可得到最终像素组成的三角形。
有时一个像素点可能在两个三角形的边上,应该属于哪个三角形可以根据自己需要定义。
加速光栅化
可以通过一些方法加速这个过程
- 使用一个bounding box来包围三角形,只对box内的像素进行判断。
- 使用下图给出的方式对像素进行遍历