在模型空間,世界空間,相機空間和剪裁空間中三角面上的紋理坐標與空間坐標是線性關系,按空間坐標進行線性插值即可求得紋理坐標。
但在透視投影模式下在歸一化設備空間和視口空間中紋理坐標與空間坐標就不再是線性關系了,要在歸一化設備空間或視口空間插值計算紋理坐標,需要進行非線性插值。
其原因就在於透視投影模式下由剪裁空間到歸一化設備空間進行了一步透視除法。
在光柵化過程中,我們通常都是要在視口空間進行紋理插值,所以我們這里重點推導視口空間中紋理坐標的插值方法。
設相機空間中的坐標為(x,y,z),其變換到剪裁空間中的坐標為(xc,yc,zc),經過透視除法變換到歸一化設備空間(xd,yd,zd),然后再經過視口變換變換到視口空間(xv,yv,zv)。
有關系:(參考:http://user.qzone.qq.com/350479720/blog/1310060277)
(根據透視投影矩陣:)
xc=x*(cot(fovy/2)/aspect)
yc=y*cot(fovy/2)
zc=-(f+n)/(f-n)*z-2fn/(f-n)
wc=-z
(根據透視除法:)
xd=xc/wc
yd=yc/wc
zd=zc/wc
wd=1
(根據視口矩陣:)
xv=0.5*width*xd+vx+0.5*width (vx,vy為視口左下角坐標)
yv=0.5*height*yd+vy+0.5*height
zv=0.5*zd+0.5
根據相機空間中三角面上的x,y,z為線性關系,有:
Ax+By+Cz+D=0
兩邊除以z得:A(x/z)+B(x/z)+C+D/z=0 (1)
由於
xd=xc/wc=-x/z*(cot(fovy/2)/aspect)
yd=yc/wc=-y/z*cot(fovy/2)
zd=zc/wc=(f+n)/(f-n)+2fn/(f-n)*(1/z)
代入(1)式得:
A(-xd*aspect/cot(fovy/2))+B(-yd/cot(fovy/2))+C+D(zd-(f+n)/(f-n))(f-n)/(2fn)=0
合並一下常數項得:
A'*xd+B'*yd+C'+D'*zd=0,其中A',B',C',D'均為常數。
可見xd,yd,zd是線性關系。
又由於xv與xd是線性關系,yv與yd是線性關系,zv與zd是線性關系,所以xv,yv,zv是線性關系,即:
zv=L(xv,yv) -----(結論1)
所以視口空間里深度值可以能過線性插值計算。
再來看紋理坐標:
由於三角面在相機空間中紋理坐標與空間坐標是線性關系,所以有:
s=Ax+By+Cz+D。
兩邊除以z得:
s/z=A(x/z)+B(y/z)+C+D/z (2)
由於
xd=xc/wc=-x/z*(cot(fovy/2)/aspect)
yd=yc/wc=-y/z*cot(fovy/2)
zd=zc/wc=(f+n)/(f-n)+2fn/(f-n)*(1/z)
代入(2)式得:
s/z=A(-xd*aspect/cot(fovy/2))+B(-yd/cot(fovy/2))+C+D(zd-(f+n)/(f-n))(f-n)/(2fn)
合並一下常數項得:
s/z=A'*xd+B'*yd+C'+D'*zd,其中A',B',C',D'均為常數。
即s/z=L(xd,yd,zd)
由於xv與xd是線性關系,yv與yd是線性關系,zv與zd是線性關系,所以
s/z=L(xv,yv,zv)
由於zv=L(xv,yv),所以
s/z=L(xv,yv)
由於zd=(f+n)/(f-n)+2fn/(f-n)*(1/z)及zv=0.5*zd+0.5,所以1/z=((zv-0.5)*2-(f+n)/(f-n))*(f-n)/(2fn),代入上式得:
s*((zv-0.5)*2-(f+n)/(f-n))*(f-n)/(2fn)=L(xv,yv)
上式可簡化為:s*(zv-f/(f-n))=L(xv,yv)
類似有:t*(zv-f/(f-n))=L(xv,yv)
----(結論2)
根據結論1和結論2就可以得到透視投影模式下在視口空間插值計算紋理坐標的方法了:
首先通過線性插值計算zv,然后通過線性插值計算s*(zv-f/(f-n))和t*(zv-f/(f-n)),設結果為S和T,則
s=S/(zv-f/(f-n))
t=T/(zv-f/(f-n))
這樣就得到了透視正確的紋理坐標(s,t)。
----
參考:http://blog.csdn.net/popy007/article/details/5570803#reply
