点顶点坐标固定
我本质上是试图了解GPU在光栅化过程中如何将浮动顶点坐标转换为定点数。
我读过这篇很好的文章,这篇文章已经解释了很多东西,但它也让我感到困惑。 因此,文章解释说,因为我们使用32位整数和以下形式(a - b)*(c - d) - (e - f)*(g - h)
的边函数,所以我们被限制在范围[-16384,16383]。 我明白我们如何得到这个数字。 这是我的问题:
简短的回答是,在三角形已被剪裁的同时,它们尚未被剪裁到视口(0,0 - 图像宽度,图像高度)。 相反,它们被剪裁到保护带剪裁区域,这是一个围绕视口的较大矩形。 位于视口之外但位于保护带剪辑区域内的顶点坐标可以具有负坐标。
有(至少)三种类型的三角形裁剪。 第一个是“解析剪辑”,即在计算三角形边与保护带剪辑区域边的交点(如果它们重叠时),然后在这些点处切掉三角形并将其余部分细分为较小的三角形,每一个现在都在剪辑区域内。 第二种类型是当三角形边界框被裁剪到视口以查找光栅化时迭代的像素范围(注意,这不会更改三角形顶点坐标)。 第三种类型是文章中描述的每像素测试,您在屏幕上迭代并测试每个像素以查看它是否在三角形内。
除此之外,取决于实施方式,屏幕的中心可以在内部被定义为(0,0)用于裁剪计算,这意味着屏幕左侧的任何东西将具有负的x坐标。
注意:我不是GPU工程师,所以这只是一个高级概念答案:
文中给出的解释中的关键词是增量评估。 看看orient2d
方程:
int orient2d(const Point2D& a, const Point2D& b, const Point2D& c)
{
return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
}
点a
和b
是三角形顶点,而点c
是屏幕坐标。 对于给定的三角形,当您迭代屏幕坐标范围时,三角形顶点将保持不变,只会指向c
变化。 增量评估意味着您只需计算与之前评估方程式相比已发生的变化。
假设我们对方程进行一次评估并得到结果w0
:
w0 = (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);
然后cx
增加一个数量s
(每像素步长)。 w0
的新价值将是:
w0_new = (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x+s-a.x);
从第二个方程中减去第一个方程,我们得到:
w0_new - w0 = -(b.y-a.y)*s;
-(by-ay)*s
对于一个给定的三角形是一个常数值,因为每次( s
是相同的量(一个像素),并且如前所述的a
和b
也是恒定的。 我们可以计算一次并将其存储在一个变量中(称之为w0_step
),然后计算结果减至:
w0_new = w0 + w0step;
您可以对w1
和w2
执行此操作,并为cy
步骤执行类似的操作。 这允许更精确的原因是每像素方程不再包含定点乘法,这是导致溢出的原因。 GPU可以对每个三角形执行一次高精度计算(例如,以64位),然后对每个像素执行一次较低精度(例如32位)。