透視矯正插值的祕密

透視矯正插值






傳統的GPU渲染流水線(管線)是基於光柵化的一套流程,之所以要強調傳統,是爲了將之區別於基於光線追蹤(ray trace)的流水線和基於體素化的流水線。在光柵管線中,最基本的2個着色器是頂點着色器和像素着色器,在下圖中,除了2個着色器可編程,中間三個時鐘節點都是固定的,只能配置不可編程。


想要了解什麼是“透視矯正插值”,先要知道什麼是插值,插值發生在流水線的光柵化階段,這一階段將根據三角形三個頂點的頂點屬性值(座標、法線、UV、顏色等)決定其中每一個像素的插值屬性。



最簡單的插值辦法就是線性插值,所以我們先來了解一下什麼是線性變換。如果2個變量之間可以用y=kx+b表示,那麼x和y就是線性相關,從x變換到y就是線性變換,比如下圖中,每個頂點乘上一個同維度的線性矩陣後,新的形狀保持了一些特性:平行線仍然是平行的,各處密度均勻,原點不變。如果原點位置變化的話那就得加上平移,線性矩陣變成仿射矩陣。




那什麼是線性插值呢?即均勻地插值,比如線段的中點的插值一定是兩端之和處以2,這個例子是一維的插值,多維也是類似。下圖中列舉了頂點色和頂點法線的線性插值。



線性插值有問題嗎,爲什麼要對它進行矯正??這要看情況,如果是正交投影后的光柵階段,線性插值是正確的,但透視投影就比較複雜了。在上個月的分享《視錐體:初等幾何解析》中,我們探討了透視投影中最重要的幾何模型:視椎體。在這個模型中物體有“近大遠小”的客觀自然規律,所以屏幕三角形中不同部位的密度是不均勻的。


關於“密度”可以這樣理解:在原始三角形上均勻的撒一些散點,待它被投影到屏幕三角形上之後,這些點是否仍然分佈均勻?想象一下,很顯然在正交投影的情況下,是均勻的,但透視投影中,距離相機近的部位散點更稀疏,遠處的散點更密集。



於是我們以UV插值爲例,如果仍然使用線性插值,會出現下圖中中間那種情況:三角形中每個方塊都是面積相等的平行四邊形。但這不符合自然規律,正確但景象應該是下圖右邊的樣子。



所以怎麼辦呢,不能簡單的線性插值,所以我們要找到插值和插值點之間真正的函數關係,所以我引入了下面的視錐側剖圖:其中O點是攝像機,L是近截面,ax+bz=c是三角形。我們抽象一個虛擬的插值點t,範圍是0~1,t從(P1,-e)出發,勻速運動至(p2,-e),t的值也勻速地從0增長至1。圖中可以看出,近截面上的均勻散點反投影到三角形上時變得不均勻了,此外還能得出,插值點的x座標P與t線性相關。




如果我們做如下圖的相似三角形,還能得出x/z與t也線性相關。



然後我們將上圖中的等式帶入到原三角線的方程中又得到如下圖的等式,其中紅色字符都是變量,因此1/z和t也線性相關。根據線性相關的傳遞性,x與z與Q都線性相關,最終我們能推導出Q/z與t線性相關。



於是能夠得出結論:在原始三角形上,插值與插值點的位置線性相關,但在透視投影后的屏幕三角形上,插值與Z的比值與插值點的位置線性相關。所以這就是矯正的方法:不能按照線性函數來插值,而應該按照下圖中非線性的公式來插值。



以上公式的詳細推導過程可以參考下面列舉的參考資料。



本文分享自微信公衆號 - WebHub(myWebHub)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章