我正在努力研究/理解栅格化算法,并且已经发布了一些与此相关的帖子,但不幸的是没有得到多少答案:
在第一个问题中,我想对一个四角体进行栅格化,但现在我将把自己限制在一个三角形上,这是标准的渲染基元。
所以我在这个问题上的问题是,准确地知道,如果一个给定的像素是在一个三角形中,那么使用哪种技术。我一直在使用边缘函数方法,这是可以的。假设我需要循环bbox的所有像素围绕一个2D三角。
float dX0 = (v1.x - v0.x);
float dY0 = (v1.y - v0.y);
float dX1 = (v2.x - v1.x);
float dY1 = (v2.y - v1.y);
float dX2 = (v0.x - v2.x);
float dY2 = (v0.y - v2.y);
for (int y = ymin; y <= ymax; ++y) {
for (int x = xmin; x <= xmax; ++x) {
float xctr = x + 0.5;
float yctr = y + 0.5;
float s0 = (xctr - v0.x) * dX0 - (yctr - v0.y) * dY0;
float s1 = (xctr - v1.x) * dX1 - (yctr - v1.y) * dY1;
float s2 = (xctr - v2.x) * dX2 - (yctr - v2.y) * dY2;
if (s0 >= 0 && s1 >= 0 && s2 >= 0) {
// point is in triangle
}
}
}我也尝试过以重心为中心的方法。计算三角形中点的s和t,如果(s + t) <= 1,那么我知道点在三角形中。
因此,我有几个问题:
1)在皮涅达[88]的论文中说,如果沿x或y移动,只需简单地添加边函数的结果即可。我引述如下:
The edge functions may then be computed incrementally for a unit step in the X or Y direction:
Ei(x+l,y)=Ei(x,y)+dYi,
Ei(x-1,y)=Ei(x,y)-dYi,
Ei(x,y+l)=Ei(x,y)-dXi,
Ei(x,y-l)=Ei(x,y)+dXi.所以这没问题,我明白为什么会这样,但是在一般情况下,我们会进行超采样,甚至随机采样(将像素分成4x4样本,这些样本会被抖动),这种方法是否仍然是有益的?
( 2)我仍然不知道如何用边函数插值计算s/t/z。有人能帮我做这件事或者给我指几页来解释这一点吗?
( 3)现在我研究了其他的网格化三角形的方法,比如Bresenham算法,但是似乎到处都说它只在不动点坐标上工作?我很困惑。投影后三角形顶点以浮点形式存在。如何从浮点到不动点坐标?
发布于 2015-01-29 13:06:44
再化
首先,一个典型的栅格化算法不会像你正在尝试的那样,遍历投影三角形的整个边框,因为这样做太慢了。其想法是:
你会看到这样的东西:
* v2
/|\
/ | \
/ | \
/ T1|T2 \
v1 *----+----* v3现在,对于栅格化三角形T1,您可以让X迭代从v1.x到v2.x,并使用边的斜率来计算Y在X上对三角形切片应该迭代的范围。
这个Y-范围的边界对于每个垂直切片都有常数增量,所以您可以将这些增量表示为小数(固定的或浮点数),或者使用Bresenham算法。
三角形T2的想法也是一样的。
多层
当使用抖动样本进行多采样时,您将决定每个单独的样本是否位于三角形内,基本上都是这样做的,但这仅对三角形边缘的像素是必要的。
然而,纹理查找只需要对每个像素进行一次(覆盖多个样本)。
如果你想计算每个样本的深度,每像素深度增量基本上必须乘以像素质心的样本的分数抖动。
插值纹理坐标
现在,如果我们考虑栅格化算法,可以认为X或Y中的每一个增量都转化为S、T和Z中的增量,这基本上可以工作,但会导致扭曲,因为S,T,Z的线性插值不考虑深度除法。
与其试图将图像空间坐标转换回3D场景坐标,还可以(而且更便宜)从简单计算的坐标中计算出校正的S、T、Z。
您可以查看此PDF,以找到校正因子的公式:http://web.cs.ucdavis.edu/~amenta/s12/perspectiveCorrect.pdf
https://stackoverflow.com/questions/28195272
复制相似问题