14.6 OpenGL图元装配和光栅化:多边形

多边形 Polygons

多边形是由三角形带、三角形扇或一系列独立三角形产生的三角形产生的。 与点和线段一样,多边形光栅化由多个变量控制。 通过使用目标 POLYGON_SMOOTH 调用 Enable 或 Disable 来启用或禁用多边形抗锯齿。

基本多边形光栅化 Basic Polygon Rasterization

根据多边形的面积符号确定多边形是正向还是背向。面积通过多边形的窗口坐标计算,使用glFrontFace函数来设置多边形的方向。

通过调用glCullFace函数设置多边形剔除模式,可以剔除前向、后向或两者都剔除的多边形。剔除功能可以通过调用EnableDisable函数,目标为CULL_FACE来启用或禁用。

对于由多边形光栅化产生的片段,采用点采样规则。首先根据多边形顶点的窗口坐标形成二维投影,并将位于此投影多边形内部的所有片段中心标记为要被光栅化的片段。针对位于多边形边缘上的片段中心,特别规定:若有两个共用相同边界的多边形,且该边界上有一个片段中心,则在光栅化过程中仅有一个多边形会产生该片段。

对于每个由多边形光栅化产生的片段关联的数据值,我们首先定义三角形的重心坐标,并描述如何为三角形内的片段生成这些值。重心坐标是一组三个数a、b、c,范围均为[0, 1],满足a+b+c=1。这三个坐标能唯一地表示三角形内任意一点p,表达式为: p = apa + bpb + c*pc, 其中pa、pb、pc分别为三角形的三个顶点。

给定三角形顶点pa、pb、pc处的关联数据fa、fb、fc,可以按以下公式计算三角形光栅化产生的片段的相应数据值f: f = (afa/wa + bfb/wb + cfc/wc) / (a/wa + b/wb + c/wc) 这里的wa、wb和wc分别是pa、pb和pc的裁剪w坐标,而a、b、c则是片段中心对应的重心坐标,必须精确对应于片段中心的坐标。

深度值的插值有所不同,需按照以下方式进行: z = aza + bzb + czc 其中za、zb和zc分别是pa、pb和pc的深度值。

着色器输出声明中的“noperspective”和“flat”关键字会影响其插值方式。如果不指定任何关键字,则按等式14.9所述方式进行插值。当指定“noperspective”关键字时,插值方式与深度值一样,遵循等式14.10。当指定“flat”关键字时,不进行插值,而是直接从与该图元相对应的触发顶点的输入值获取输出值。

设置多边形正向的方向

void glFrontFace( enum dir );
  • GL_CCW:表示逆时针方向为正向。
  • GL_CW:表示顺时针方向为正向。

通常情况下,逆时针方向被认为是正向。

设置多边形剔除的模式

void glCullFace( enum mode );
  • GL_FRONT:表示剔除正向面。
  • GL_BACK:表示剔除背向面。
  • GL_FRONT_AND_BACK:表示剔除正向和背向面。

默认情况下,OpenGL 的剔除模式通常是 GL_BACK,即只剔除背向观察者的多边形。启用或禁用多边形剔除功能需要调用glEnable(GL_CULL_FACE) 和 glDisable(GL_CULL_FACE) 函数。

抗锯齿 Antialiasing

当一个多边形与片段方块(像素区域)有交集时,会为该片段计算一个关联数据值。这个数据值是通过对多边形内部与片段方块交集区域的数据进行积分得到的,并且将这个积分值除以交集面积来归一化,这样可以确保即使在部分覆盖的片段上,颜色和其它属性也能按照实际覆盖比例进行插值。

对于完全位于多边形内部的片段,由于其覆盖率为100%,可以直接使用该片段中心处的数据值代替整个片段区域的积分运算,这样既简化了计算过程,又保证了结果的准确性。这种技术提高了图形渲染的质量,特别是在呈现复杂形状和边缘时,能够有效地消除锯齿现象,提供更为平滑自然的视觉效果。

控制多边形光栅化的选项 Options Controlling Polygon Rasterization

控制多边形在光栅化过程中的渲染方式

void glPolygonMode( enum face, enum mode );
  • face:必须是FRONT_AND_BACK
  • mode 渲染模式:
    • GL_POINT:多边形的顶点将被渲染为点。
    • GL_LINE:多边形的边将被渲染为线段。
    • GL_FILL:多边形将被填充。

需要注意的是,这些模式仅影响最终多边形的光栅化阶段,在此之前,多边形会先经过裁剪和可能的剔除操作。

另外,多边形的抗锯齿效果只针对 PolygonMode 设置为 FILL 状态时生效。对于 POINT 或 LINE 模式,分别适用点的抗锯齿或线段的抗锯齿技术。

深度偏移 Depth Offset

多边形的深度值偏移可以通过计算得出的单个值来偏移。确定这个值的函数由以下命令指定:

void glPolygonOffsetClamp(float factor, float units, float clamp);
void glPolygonOffset(float factor, float units);
  • factor 用于缩放多边形最大深度斜率的值;
  • units 用于乘以最小可分辨差异。
  • clamp 参数将其钳制值到指定的最小或最大值。当clamp为正数时,它将限制最终偏移量的最大值;当clamp为负数时,限制最小值;若clamp为0或NaN,则不进行钳制操作。
  • factorunitsclamp 的值可以是正数、负数或零。调用 PolygonOffset 命令相当于调用 PolygonOffsetClamp 命令,并将 clamp 设为零。

m 是三角形的最大深度斜率。

r 是最小可分辨差异,是一个依赖于深度缓冲区表示的实现相关参数。

偏移值 o 为:

  • clamp = 0NaN 时,偏移值为 m × factor + r × units。
  • clamp > 0 时,偏移值为 min(m × factor + r × units, clamp)。
  • clamp < 0 时,偏移值为 max(m × factor + r × units, clamp)。

偏移值将应用于深度值的范围为 [0, 1]

多边形偏移需要使用 glEnable 开启 POLYGON_OFFSET_POINTPOLYGON_OFFSET_LINEPOLYGON_OFFSET_FILL*,分别确定在 POINTLINEFILL 模式下的多边形光栅化中是否应用多边形偏移。

以及一个浮点状态值 POLYGON_OFFSET_CLAMP,用于指定偏移钳制值。

多边形偏移的初始值是 FALSE,偏移钳制值的初始值是 0.0。如果启用了多边形偏移点、线或填充,则在 POINTLINEFILL 模式下进行多边形光栅化时,会将偏移值添加到每个片段的深度值中。对于固定点深度缓冲区,片段深度值始终通过偏移添加后进行钳制,即使深度缓冲区使用浮点表示也是如此。

多边形多重采样光栅化 Polygon Multisample Rasterization

当启用 MULTISAMPLE 功能,并且 SAMPLE_BUFFERS 的值为1时,不论是否启用了多边形抗锯齿(POLYGON_SMOOTH),多边形都会按照以下算法进行光栅化。对于每个帧缓冲区像素,只要满足点采样标准(在第14.6.1节中描述的规则),光栅化过程就会为该像素生成一个片段。

如果一个多边形根据其朝向和CullFace模式被剔除,则在光栅化过程中不会产生任何片段。与满足点采样标准的样本点对应的覆盖位设置为1,其他覆盖位则设置为0。每个多边形关联的数据值按第14.6.1节中的方式生成,但这里使用的是相应样本位置而非片段中心来计算数据值。实现可以选择通过重心坐标评估法,在像素内的任意位置(包括但不限于片段中心或任一样本位置)计算相关数据,并将其分配给多个样本。

noperspectiveflat 修饰符同样影响着色器输出的插值方式,这与第14.6.1节中描述的基本多边形光栅化的方式相同。

上述光栅化方法仅适用于 PolygonMode 设置为 FILL 状态的情况。对于点和线段,分别适用(点的多采样光栅化)和(线段的多采样光栅化)中所描述的光栅化算法。

多边形光栅化状态 Polygon Rasterization State

多边形光栅化所需的系统状态包括以下各项当前的状态:

  1. 多边形抗锯齿(Polygon Antialiasing)的启用或禁用状态。
  2. 当前设置的 PolygonMode 值,它可以是点模式、线段模式或填充模式。
  3. 点模式、线段模式以及填充模式下的多边形偏移(Polygon Offset)是否启用或禁用。
  4. 多边形偏移公式中的因子(factor)和偏差值(bias)。

初始状态下,多边形抗锯齿功能是被禁用的。PolygonMode 的初始设置为 FILL 模式,这意味着默认对多边形进行填充渲染。另外,多边形偏移的初始因子和偏差值都设定为0,并且在所有模式下最初都是禁用多边形偏移的。这意味着,在开始时,系统不会应用任何额外的深度偏移来处理重叠几何体的问题。

你可能感兴趣的:(OpenGL,图形渲染)