纹理采样的理论与实现

苦于这方面的资料太少,于是自己推了一下!

以平底三角形为例(三角形并无剪切)

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,我不喜欢加势利的人。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值