Computer Graphics 06
The Graphics Pipeline
前面几章已经建立了所需的数学基础(scaffolding)
现在主要讨论第二种主要的rendering 方式。
—在屏幕上一个接着一个绘制物体,也即object order rendering
不同于ray tracing 的方式,通过像素找物体,现在会反过来通过物体找像素
**在一张被几何图元(geometric primitive)占满的图像上的所有像素的过程,称之为rasterization(光栅化)**,所以object order rendering也称之为光栅化渲染
而实现这一操作的操作序列,称之为图形渲染管线,graphics pipeline
这种方法的成功,来源于它的效率。
对于大型场景,对数据存储模式的管理 是至关重要的操作。而且制作一个整个场景的通道来访问几何的每一个bit一次,比重复地搜索场景来检索所需的场景更加有有时。
object-order rendering不只有一种方法。
hardware 硬件pipeline使用OpenGL,Direct3D等API
software pipeline使用鱼电影制作,提供了像RenderMan这样地API
硬件渲染管线需要运行地很快,使得足以支撑起实时游戏,可视化和用户交互
Production pipeline(生产管线)则追求高质量动画、视觉效果,但是这会花费很多时间。
Rasterization
Line Drawing
使用隐式线条方程
用隐式方程画线条最普遍的算法是midpoint algorithm
这种算法能够画出和Bresenham algorithm一样的线条,但是稍微更加直接。
见P38
常见的斜截式(slope-intercept) y = mx + b
b称为y-intercept,
slope-intercept 有时有点尴尬(awkward),因为它不能表示x = 0,不然m需要infinite
这时候使用隐式表达式(implicit equation) Ax + By + C = 0
还有两点式(y0 - y1) x + (x1 - x0)y + C = 0
C的话代入任意一个点就可以得到
最终
(y0 - y1) x + (x1 - x0)y + x0 y1 - x1y0 = 0
我们假设x0<=x1,如果不正确,就交换两个点,斜率
slope m =(y1 - y 0)/(x1 - x0);
以下假设m在(0,1)区间
一个很有效的方法是,通过比较两个预选像素的中点和line,如果line在中点上面,就画(x+1,y+1)
不然就画(x+1,y)
那么如何比较(x+1,y+0.5)和线条呢
f(x + 1,y + 0.5) < 0 then y = y + 1
详情见P182
Triangle Rasterization
三角形内重心(barycentric coordinates)的颜色
是 c = a * c0 + b * c1 + r * c2
另一个rasterizing triangle的细节(subtlety)是共享顶点和边。
这意味着相邻(adjacent)三角形之间没有间隙,我们可以用midpoint algorithm来画每个
三角形的边,然后填充内部像素
光栅化三角形,需要避免顺序问题,消除间隙,而方法则是,按照惯例(convention),当且仅当像素的中心在三角形内,才进行光栅化。
暴力算法(brute force algorithm)
使用中心判断是否光栅化
Dealing with Pixels on Triangle Edges
我们还没有讨论如果像素中心在三角形的边缘该怎么办,
根据上面的思路,如果不光栅化,那么势必会小一圈,相邻三角形可能会有一个大的间隙;如果光栅化,相比较前者好一些,但仍有问题:如果三角形都是transparent的,这将会造成double-coloring,毕竟本意是半透明,但是却画了两次。
所以我们真的确实需要裁定(award)具体哪一个像素,然后我们希望这个过程能够很简单。
其中一个方法是,标记任意视线之外的点确定为公共边的一侧,并且指定这个边是要绘制的。
Perspective Correct Interpolation
当interpolating quantities 插值大量的,例如纹理坐标或者3d坐标等需要在3d三角上线性改变
的数据时
在实现“纠正视觉透视”有一些subtleties(小方法,精妙的细节)
当透视校正很重要时我们会使用纹理坐标作为一种数量的指标(example)
3d空间线性值很重要是,上述考虑也适用于任何参数
事情不会那么简单的原因是,单纯的屏幕空间纹理坐标插值,会导致不正确的图像。如下图