CG笔记之一——透视投影
于是,投影事實上成了投影變換。投影變換需要滿足兩個基本要求[1]:
1.保持depth的位序;
2.將直線變換為直線。
在x和y方向仍根據投影方法定義(投射在攝像機平面上的坐標),而在z方向上,需要引入偽距離映射(pseudo-distance),數學上,透視投影的偽距離映射具有形式z' = A + B / z。假設z方向截斷分別為n和f = 1 / rf,截斷分別映射為pn和pf。于是列寫方程式1:
pn = A + B / n?? (式1)
pf = A + B * rf (式2)
解得:
A = (n * rf - pf) / (n * rf - 1)?(式3)
B = n * (pf - pn) / (n * rf - 1) (式4)
可以證明,相應的齊次坐標變換矩陣為:
[ d, 0, 0, 0;
? 0, d, 0, 0;
? 0, 0, A, B;
? 0, 0, 1, 0]??? (式5)
一個很賞心悅目的方案是將n=d(目屏距)映射為0,而將rf=0(無窮遠處)映射為1,這種情況下:A=1, B=-d。然而事實上,為了能夠提供較好的depth分辨效果,n和f的選擇(尤其是f)非常重要,f必須能容納所有需要關心的物體,需要足夠大,但是過大的話會導致depth分辨率的相對降低;而pn和pf則主要取決于為depth分配的位數,通常,現代顯卡為depth配置了32位定點數。而透視投影的偽距離映射的一個較好的性質是,它對較近的物體提供了較大的分辨率,較遠的物體則即使由于分辨率低而發生錯誤也是可以接受的。
然而在OpenGL中,用一個錐形頂點在圓點,截平面與z = 0平面平行的平截頭體(frustum)向任意矩形映射的方式定義透視投影。它是一種更一般的透視投影形式。
列寫關系式:
px = kx * x / z + dx??? (式6)
py = ky * y / z + dy??? (式7)
pz = kz / z + dz (式8)
可以導出齊次線性變換矩陣為:
P = [ kx, ?0, dx, 0;
?????? 0, ky, dy, 0;
???????0,??0, dz, kz;
???????0,? 0,? 1, 0]??? (式9)
注意到:
??? M = [ 1, 0, 0, dx;
????????? 0, 1, 0, dy;
????????? 0, 0, 1,?dz;
????????? 0, 0, 0,?1]
??? A = [?kx, 0,? 0, 0;
?????????? 0, ky, 0, 0;
???????????0, 0,? 0, kz;
???????????0, 0,? 1, 0]
有P = M * A??? (式10)
即P變換矩陣由投影(A矩陣)和屏幕平移(M矩陣)兩部分變換組成。
根據映射關系:
(x0, ?, z0) -> (px0, ?, pz0), (x1, ?, z0) -> (px1, ?, pz0)??? (式11)
(?, y0, z0) -> (?, py0, pz0), (?, y1, z0) -> (?, py1, pz0)??? (式12)
(?, ?, z0) -> (?, ?, pz0), (?, ?, z1) -> (?, ?, pz1)??? (式13)
可以解得:
kx = z0 * (px1 - px0) / (x1 - x0), dx = (x1 * px0 - x0 * px1) / (x1 - x0)??? (式14)
ky = z0 * (py1 - py0) / (y1 - y0), dy = (y1 * py0 - y0 * py1) / (y1 - y0)??? (式15)
kz = z0 * (pz0 - pz1) / (1 - z0 / z1 ), dz = (pz1 - pz0 * z0 / z1) / (1 - z0 / z1)??? (式16)
注意到,kz是小于0的,這使得式8給出的偽距離映射是合法的。
注釋
1 本筆記采用傳統的z軸,即從眼睛指向屏幕,x從左至右,y從上至下(符合光柵掃描順序),因此它仍是右手系的。
參考文獻
[1] 3-D Computer Graphics, A Mathematical Introduction with OpenGL, Samuel R. Buss
轉載于:https://www.cnblogs.com/quanben/archive/2007/04/08/3129011.html
總結
以上是生活随笔為你收集整理的CG笔记之一——透视投影的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Server 2005与2000
- 下一篇: Some thoughts on my