2.11 图元装配和着色后顶点处理
处理顶点之后,根据绘制函数(见2.6.1和2.8)的mode参数,顶点被装配到图元中。在接下来的章节中将会介绍图元装配的步骤
- 裁剪坐标系的透视分割(2.12节)
- 视口映射,包括深度范围缩放(2.12.1节)
- 图元侧键(2.13节)
- 裁剪可变输出(2.13.1节)
2.12 坐标变换
顶点着色器执行后产生一个顶点坐标系gl_Position,这个坐标系被认为是裁剪坐标。裁剪坐标系通过透视分割后产生归一化的设备坐标系,再通过视口转换变成窗口坐标系(如果2.4)。
裁剪坐标系是一个四维的齐次向量,按照顺序由x,y,z和w坐标组成。如果顶点裁剪坐标系是
那么顶点的归一化设备坐标系是:
2.12.1 控制视口
视口变换由视口的像素宽高决定,即,各自的中心点也是像素衡量的中心。顶点的窗口坐标 通过下面计算得到:
作用于的因子和偏移量由和共同决定,使用函数:
void DepthRangef(clampf n, clampf f)
每个n
和f
都被限制在[0,1]中,所有的参数都是clampf类型。是被认为是以固定点表示的,其位数至少和帧缓冲区的深度缓冲区的位数相同,如果用在2.1.2节中帧缓冲区部分中描述的那样。
视口转换参数被指定使用:
void Viewport(int x, int y ,sizei w, sizei h)
其中,x和y给出了视口左下角的窗口坐标系的x和y值,w和h各自给出了视口的长和宽。视口的参数在上面的等式中通过这些值建立:,
,
当被指定时,视口的宽和长会被牵拉到实现相关的最大值。最大的长宽值可以调用一个合适的Get
函数来查询到(见第6章)。最大的视口维度必须要大于或者等于要被渲染显示的可视的维度。w或者h如果是负的,将会产生INVALED_VALUE错误。
实现视口转换需要四个整形数和两个固定的浮点值。在初始状态,w和h各自被设置为窗口的宽和高,然后传递给GL做渲染。被设置为。n和f分别被设置为0.0和1.0。
2.13 图元裁剪
图元按照裁剪量裁剪,在裁剪坐标系中,裁剪量被定义为
如果要处理的图元是点,这个点在近裁剪平面和远裁剪平面之外,裁剪机制将会忽略这个点。
如果要处理的图元是一个线段,整个线段都在近裁剪平面和远裁剪平面之内,裁剪机制不会做处理,如果整个线段都在两个裁剪平面之外,裁剪机制也会忽略它。
如果线段的一部分在俩那个裁剪平面之内,另一部分在外面,那么线段将会根据俩那个平面重新裁剪,并且顶点的顶点坐标系也会重新计算。
裁剪操作产生一个值,对每个裁剪操作过的顶点都有。如果裁剪过的顶点的坐标系为P,原始的顶点坐标系为P1和P2,那么有下面公式给出:
如果图元是三角形,每个边缘全部都在裁剪区域内才会被执行,部分在外的顶点会被裁剪,全部在外的顶点也会被忽略。裁剪操作会引起三角形的边被裁剪,但因为连接性必须被保持,这些被裁剪的边使用裁剪时裁剪区域的边际产生的新的边来重新连接起来。因此,裁剪操作可能会引进一个新的顶点给三角形,从而编程一个广义上的多边形。
如果一个三角形和裁剪区域的边界相交,被裁剪的三角形必须包含这个边界上的一点。
线段或者三角形的顶点拥有不同符号的值时,可能会在裁剪操作之后产生多个相互连接的部分。GL的实现不要求处理这种情况。这意味着,只有在的区域中的图元的部分需要被裁剪操作处理。
2.13.1 裁剪变量输出
之后,顶点着色器的varying变量被裁剪了。在裁剪区域中的顶点和相关的varying变量的值不受裁剪操作影响。如果图元被裁剪了,通过裁剪操作产生的分配给顶点的varying值就是裁剪过后的值。
未裁剪的边上的两个顶点P1和P2分配的varying变量的值为c1和c2。对于一个裁剪过的P值,其的值(见2.13)通常和P的值有以下关系:
(通过放缩因子放缩一个varying变量的值意味着放缩每一个x,y,z和w的值)
多边形裁剪操作可能会产生一个沿着裁剪区域边界的被裁剪的顶点。多边形裁剪是通过一次裁剪剪辑区域边界的一个平面来处理这种情况的。varying值的裁剪操作也是这样完成的,被才见的点总是出现在多边形的边和裁剪区域边界相交的地方。