圖形學筆記 —— 透視除法
本文采用左手坐標系,即z軸向屏幕里增長。
透視投影變換
透視投影變換,有三個詞組成:透視、投影、變換。我們逐個來理解。
- 透視:我理解為“有遠近感”的,也就是我們平時所說的近大遠小。而相對地,近少遠多:你站在山頂上,近處你只能看見附近幾棵花花草草,但是遠處你可以遠眺整個城市這么多東西。如果你把人視野內的東西還原回去三維,它們大概會分布在一個圓台上,不是么。
- 說到投影你會想到什么?如果是我,我會想到降維。將一條平面上的線段投影到一維的坐標軸上,將一個三維上的物體投影到二維平面上,這就是我們平時接觸到的投影。透視投影變換,就是后者,將三維的物體拍扁成二維的。好了,這個“二維的地方”是哪里呢:就是視網膜了。
- 變換:就是線性變換,這說明我們需要用一個矩陣去把它表達出來,一個齊次坐標變換矩陣。
透視投影變換的思路是:將想要變換的點,與瞳孔連接起來,成為一條視線。然后這條視線,與視網膜的交點,就是變換后的點了。:

如上圖所示,點 \((x, y, z)\) 在紫色的視線上穿過瞳孔,在視網膜上成像,像的y坐標y'就是紅色的那一段。不過我們知道眼球里的成像是反的,所以實際上我們求的不是紅色的那一段,而是與紅色那一段全等的綠色那一段。很顯然,我們可以找到相似三角的關系,我們假使視網膜(或者綠線)到瞳孔的距離是\(z_{r}\),那么變換后綠點:
\(1/z\) 這個因子可以通過令 \(\omega = z\) 來實現,寫成矩陣,就是:
透視除法
可以一眼看出,上面那個矩陣的秩只有3,這說明我們損失了一個維度(從這個矩陣的求法也可以看出,損失的是深度z維)。弄丟了深度信息,這使得深度測試和裁剪都非常難以執行。於是我們想了一個辦法讓深度信息得以保留,這就是透視除法。透視仍然是透視,那么除法是什么呢?稍后有解答。
透視除法的思路是:將視野(平截頭體)內所有的東西都變形,然后擠壓到一個小立方體里面。就像一個黑洞,當你掉進一個針孔般大的黑洞的時候,你會被擠壓得比針孔還要小很多(我不懂物理這是我胡說的)。

好了,用什么數學方法去擠壓它呢?答案就是除法:(下圖中,兩條綠線分別除以兩條藍線)

這樣理解:當我們看到一個點的時候,這個點背后的所有物質都不會影響我們看到這個點的位置。將它在平截頭體內三個方向的物質數,比上它到鏡頭前三個方向的物質數,就是這個比值的意義。這樣除完之后,再將它規整成一個2x2x2的立方體,然后整個平移到原點周圍。這個立方體就叫做規則觀察體(CVV, Canonical View Volume)。我們定量分析這個過程,Y方向的視角我們設作 \(\theta\) (如上圖所標注),X方向的視角我們設作 \(\psi\),平截頭體的兩個底,前面的叫做近裁剪面,后面的叫做遠裁剪面,它們離鏡頭的距離分別設作 \(z_n, z_f\):
寫成矩陣,也即:
更直觀的求法,就是利用我們需要的是一個確定位置的2x2x2立方體這個條件,用方程將值求出來。
透視投影和透視除法的關系
事實上兩者的形式很相似,拿\(\cot \frac \theta 2\)來說,它不就是當那條綠線長度等於1的時候的 \(z_r\) 么。透視除法比透視投影多出來的,就是對片斷的深度信息的保存。另外,將它變換到一個規范立方體中也有利於裁剪的進行:只需要簡單地比較坐標是否在正方體中,否則削除這個點,或者截斷直線。
