OpenGL 像素/片段在概念上是以半整数像素为中心的 1x1 正方形。OpenGL 4.5 规范指出:
片段位于其左下角,位于整数网格坐标上。光栅化操作还涉及片段的中心,该中心从其左下角偏移 (1/2,1/2)(因此位于半整数坐标上)。
光栅化器通常假定像素中心位于整数网格上。由于我正在尝试实现正确的 OpenGL 三角形填充,因此我想知道以下过程是否合理。
让我们以剪裁坐标为(-1,-1),(+1,-1),(0,+1)的三角形为例,如下图左侧所示(假设正交投影,z=0 )。假设我们有一个(小的 5x5 帧缓冲区),我们将我们的三角形映射到通过glViewport(0,0,5,5)
如右图所示产生具有顶点 (0,0)、(5,0)、(2.5,5) 的设备坐标中的三角形。
如您所见,中心在三角形内的 13 个片段(图像中的阴影像素)应由光栅化器生成。请注意,片段中心位于半整数坐标上。要实现 OpenGL 规范,这就是结果所需要的。
扫描线多边形填充将确定扫描线与三角形相交的 x 跨度,但扫描线处于半整数 y 值,如下图所示:
硬件/固件光栅器将假定像素中心位于整数网格上,因为这是执行填充的最有效方式。在下图中,我将三角形的设备坐标移动了 (-0.5, -0.5) 以将中心放置在整数网格上:
请注意,像素中心现在确实在整数网格上。这个光栅化器会简单地将 (0.5,0.5) 添加到每个片段中心,然后再传递给片段着色器。至少这是我的计划。
处理纹理坐标似乎很简单。想象一下我分配的纹理坐标 (0,0), (1,0), (0.5,1) 如下图所示。左边的图像使用半整数像素中心(OpenGL 方式),右边的图像使用整数像素中心(硬件方式)。无论哪种方式,纹理坐标(任何附加的片段属性)最终都具有相同的值——即,不需要做任何特别的事情。
那么我的方法似乎正确吗?
- 将 (-0.5,-0.5) 添加到每个片段坐标,
- 使用硬件高效填充,
- 在生成片段中心时添加 (0.5, 0.5) ,并且
- 不要为其他片段属性出汗(它们只是解决问题)。