图形管线

2022-10-25 16:38:57 浏览数 (1)

本篇介绍

图形管线描述的是从图像输入到呈现在显示器上的一个流程。在这一篇里就会看到这个流程中间涉及的一些内容。 中间涉及的流程可以参考下图:

image.png

光栅化

光栅化按照给定的图元定点坐标,生成对应的像素,中间也会进行插值。这儿按照几个场景分别看下。

画线

在需要画线的时候,输入是线的起始点和终点。这时候光栅化要做的是决策那些像素在这条线上。采用的方法是先表示出这条线。比如可以按照 Ax By C=0的形式生成该线段的表示形式:

image.png

image.png

这样在像素层面,就可以将像素坐标代入该公式看是否在该线段上。 这样是理论情况,实际上像素坐标是整数的,如果是严格按照该公式来,就可能最后算出来的线段像素点是断开的。因此就需要在线段的开始和终点之间,每行或者每列至少需要有一个像素点被认为是在该线段上。 如下所示:

image.png

这样同一个线段就会出现多种像素的分布形式。

这时候的算法如下:

image.png

简单理解下这个算法,在起点和终点之间,每次增加x都需要有一个点位于该线段上,默认是水平的,如果满足某个条件,那么就更新y坐标。 那如何表示该条件呢?最直接的方法就是判断候选像素的中点和线段的关系。候选像素点是(x 1,y),(x 1,y 1),那么中点就是(x 1,y 0.5),如果该点在线段下面,说明线段更偏上一些,那么候选像素选(x 1,y 1),反之选(x 1,y)。

三角形

光栅化三角形需要区分出在三角形内的像素点和对三角形内像素点的颜色进行插值。这两个都可以通过重心坐标来完成。我们前面提到过,对于三角形内的任意一个点,都可以表示成如下形式:

image.png

这时候的算法如下:

image.png

image.png

还有一个需要考虑的问题是对于两个有共同边的三角形,共同边的颜色应该怎么决策?如果是不画的话,可能出现空洞,这样肯定不行,如果是画两遍的话,这样共同边的颜色又可能和两边三角形颜色都不一样,也会有问题。最合适的方法应该是只画一遍,那共同边的颜色以哪边的三角形颜色为准呢?这时候就可以定义一个特定的“离屏点”,哪个三角形接近该“离屏点”就画那个三角形的颜色。如下图所示,这时候共同边上的点的颜色就应该以左边三角形为准:

image.png

这时候的算法如下:

image.png

image.png

从算法可以看出,判断谁更接近其实就是判断哪个三角形的点和“离屏点”位于共同边的同一个方向。

z buffer

在光栅化的时候还需要有一个深度的概念,就是接近观察者的物体不能被远离观察者的物体挡住。如下图所示:

image.png

图中就是两个一样大小的圆形,结果远处的圆形把近处的挡住了,这样是不合理的。针对这种情况也有一些比较直接的算法,比如画家算法,先对图形按照远近排个序,然后从远到近进行绘制,不过这种方法实际上很少用。 实际上用的最多的是z buffer算法。其实就是给每个像素增加一个深度信息。在片段混合阶段存储每个像素点的最近图元的颜色信息。这样就不依赖图元的绘制顺序了。 那这儿就涉及到深度值的表示问题,一般是用整数表示,那么就有一个精度问题,可以简单看下。如果是有B个不同的深度值,那么深度的最小变化是(f-n)/B。 按照前面介绍的透视投影z坐标换算公式:

image.png

z是投影后的坐标,深度理论上应该记录的是投影前的坐标Zw。这时候就需要看下投影前的坐标变换替换到投影后的变化,对Zw进行求导,结果如下:

image.png

再反一下就是投影后的z变化体现到变换前的变化:

image.png

看下最大的深度值:

image.png

这儿可以看到为了高精度,就需要n大一些,f小一些。

阴影

在涉及到阴影的时候,就需要考虑是在顶点着色时处理还是片元着色时处理。定点着色会比较简单,按照顶点计算是否应该在阴影中,然后其余交给光栅化去插值。好处是运算量小,不过效果可能不会很好,由于是按照图元顶点来的,那么小于图元的细节就处理不了了。如下图所示:

image.png

可以看到高光处有明显的三角形痕迹。 另外一个方法就是在片元处理的时候计算阴影,由顶点着色器将光源的方向和点的法线信息传过来。好处是效果好一些,不过运算量会大一些。下面是片元处理的效果图:

image.png

这时候高光周围的阴影就比较自然了。

反走样

在前面介绍画线时我们提到来决策是否在线段上是按照像素来的,那么一个像素要不在线段上,要么不在,那么这样的像素值就会呈现出锯齿状,这就是走样。为了让效果更逼真一些就需要做反走样处理,其实就是对每个像素点做一个卷积,类似于低通滤波,其实就是在对边缘像素点计算颜色的时候,不是直接非黑即白,而是按照周围的像素点取平均。这时候的效果如下:

image.png

上面的是反走样处理后的,下面的是原始的锯齿线。

0 人点赞