CG筆記之一 透視投影

2021-08-22 07:47:05 字數 2335 閱讀 8264

以前以為投影也就投影了,並不了解投影也可視作座標變換,而且也是乙個齊次座標(homogeneous coordinate)系的座標變換。因此書中的介紹一開始也不明白——它說透視投影會把直線對映成曲線,還特地驗證一下,發現投影為2d空間(攝像機平面)並不會發生這種情況,在仔細一看才知道,它指的是對映到3d空間,在z方向發生了畸變。而後逐漸了解,原來z方向的位置資訊(depth)在渲染級模組處(所謂的z-buffer)有特殊用處(直線上每個點的depth均通過直線兩端的點線性插值完成,因此可能造成depth位序異常)。當然這個問題在某些場合是不會發生的,例如完全基於光線跟蹤演算法的渲染並不是這樣形成depth的。

於是,投影事實上成了投影變換。投影變換需要滿足兩個基本要求[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

openGL學習筆記十四 透視投影

三維空間物體顯示近大遠小。透視投影區域是個稜錐體 透視投影顯示效果 透視投影 define glew static include include include include include pragma comment linker,subsystem windows entry maincr...

一步步學OpenGL 12 《透視投影》

原文 csdn完整版專欄 透視投影原理其他文章 總算到了如何實現最優化顯示3d圖形的階段了 在保留物體深度立體感的前提下將3d世界的物體投影到2d平面上。乙個很典型的例子就是3d世界中往遠方延伸的公路,2d螢幕上看上去會越來越窄最後在很遠的地平線上交匯成了乙個點。我們現在要建立一種滿足上面要求的一種...

SVC筆記之一

本筆記參考advance in scalable video coding 1 在ppt介紹可伸縮編碼原理部分,有一張編碼系統框圖不是很直觀 相對於它上面那幅 需要做一些說明。假設當前幀是fn,則前一幀為fn 1,相應的運動補償分別為rn和rn 1,高精度量化通道為qh,低精度量化通道為ql。於是高...