苦于这方面的资料太少,于是自己推了一下!
以平底三角形为例(三角形并无剪切)
1。求出Pnl, Pnr的几何坐标
(1)假定扫描线是水平的,即△P0P1P2从上到下光栅化的,因此起始的扫描线为P0P0,每扫描一次
y每将增加一个像素单位
∴yrn = yln = yn = y0 + n (1)
(2)n表示第n条扫描线,yrn,yln已求出,现在求xln, xrn, uln,vln, urn, vrn, xn, yn, un,vn
解:
1.求xln, xrn:
已知直线方程的斜截式为 : y = kx + b
则直线段P0P2的方程为 :y = kx + b => b = y - kx
把P0代入得:b = y0 - kx0, 已知斜率k = (y2 - y0) / (x2 - x0),
则直线段P0P2的直线方程为:
y = kx + y0 - kx0 => yln = k*xln + y0 - kx0
由(1)得: xln = (yln - y0)/k + x0 = (y0 + n - y0)/k + x0 = n/k + x0
=> xln = [(x2 - x0) / (y2 - y0)]*n + x0
xln已求, 同理可求得xrn = [(x1 - x0) / (y1 - y0)]*n + x0
2.求urn, vrn, uln, vln:
同理可得图(2)P0P2的直线方程:
v = k1*u + v0 - k1*u0, 斜率k1 = (v2 - v0)/(u2 - u0) (1)
由(1)式得:
uln = (vln - v0)/k1 + u0 (2)
设m1 = (v2 - v0) / (y2 - y0), 它的几何意义表示为,在几何图形中每增加一个纵坐标的像素单位,对应的
纹理纵坐标增加m1个像素单位
注意:几何图形是从上到下的水平扫描线,纹理的扫描线并不是从上到下的水平扫描线,它的扫描线是通过
几何图形的信息计算得出的
∴vln = (v0 + n*m1), 把vln代入(2)式并化简得:
uln = n*(u2 - u0)/(y2-y0) + u0 (3)
所以Pnl的纹理坐标为:**************************************************************
vln = v0 + [n*(v2 - v0)/(y2 - y0)]
uln = u0 + [n*(u2 - u0)/(y2-y0)]
所有坐标
同理可求Pnr的坐标为****************************************************************
urn = [n*(u1 - u0)/(y1-y0)] + u0
vrn = [n*(v1 - v0)/(y1-y0)] + v0
注意:因为是平底三角形,所以y1 - y0 = y2 - y0
3.求un, vn:
xn,yn是点Pn 的横坐标和纵坐标,而点Pn在水平直线段PnlPnr上(平行于世界坐标轴的x轴)
根据斜截式的性质可求出图(2)PnlPnr的直线方程:
v = k2*u + vln - k2*uln
= k2(u - uln) + vln
所是vn = k2(un - uln) + vln (4)
设d = un - ul
则vn = k2*d + vln (5)
设m3 = (urn - uln)/(xrn - xln),它的几何意义表示为,在几何图形中每增加一个横坐标的像素单位,对应的
纹理横坐标增加m1个像素单位
从图可知,d = un - uln 表示Pnl到Pn的纹理横坐标的水平距离
所以,根据m3的几何意义,得d = un - uln = n2 * m3
注意其中n2表示图(1)中PnlPn的水平长度,即PnlPn的长度
∴vn = k2 * n2 * m3 + vln
把k2, m3代入上式并化简得:
vn = n2 * (vrn - vln) / (xrn - xln) + vln (6)
其中vrn, vln, xrn, xln, vln在前面已求出
根据d = un - uln = n2 * m3可求得un = n2 * (urn - uln)/(xrn - xln) + uln
其中urn, uln, xrn, xln, vln在前面已求出
所以Pn的纹理坐标为***********************************************
vn = n2 * (vrn - vln)/(xrn - xln) + vln
un = n2 * (urn - uln)/(xrn - xln) + uln
下面给出核心代码部分
xln = xrn = x0;
yln = yrn = y0;
uln = urn = u0;
vln = vrn = v0;
xn = x0; yn = y0; un = u0; vn = v0;
buffer[yn, xn] = texture[vn, un];
int dy2 = (y2 - y0);
int dy1 = (y1 - y0);
int dx2 = (x2 - x0);
int dx1 = (x1 - x0);
int du2 = (u2 - u0);
int du1 = (u1 - u0);
int dv2 = (v2 - v0);
int dv1 = (v1 - v0);
for (int yi = y0 + 1; yi <= y2; yi++)
{//垂直扫描
xln += dx2 / dy2;
uln += du2 / dy2;
vln += dv2 / dy2;
xrn += dx1 / dy1;
urn += du1 / dy1;
vrn += dv1 / dy1;
un = uln;
vn = vln;
int du = urn - uln;
int dv = vrn - vln;
int dx = xrn - xln;
for (int xi = xln; xi <= xrn; xi++)
{//水平扫描
un += du / dx;
vn += dv / dx;
buffer[yn, xn] = texture[vn, un];
}
}
如果大家喜欢游戏编程技术,可以加我QQ282891168,我不喜欢加势利的人。