【基礎】透視校正插值(Perspective-Correct Interpolation)

參考

參考博客1
參考博客2

這個問題之前好長時間都沒有弄明白,主要原因是沒有搞清爲什麼需要這個方法,今天靜下心來仔細看了幾篇資料終於想清楚了。這篇博客也主要講我對透視校正插值前因後果的理解,具體的數學推導可以看上面的參考文章。

在光柵化階段我們需要對頂點座標和定義在頂點上的屬性(法線、uv等等)進行插值,產生一系列的片元以及定義在片元上的屬性。現在有點A(XA,YA,ZA)和點B(XB,YB,ZB),以及定義在A上的屬性IA和B上的屬性IB。現在AB上有一點C(XC,YC,ZC),需要求得C上的屬性IC。線性插值的方法就是通過ABC的座標求出插值係數s,即C=s*A+(1-s)*B,那麼IC=s*IA+(1-s)*IB。這裏的I可以是任何需要插值的頂點屬性(頂點着色器的輸出),如顏色、法線、紋理座標等等。

這種插值方法顯然在線性空間中是正確的,但我們的問題是當需要對頂點屬性進行插值時,我們已經進入了光柵化階段,早就將座標轉化到非線性空間中了,這時如果直接用線性插值就會出問題。

先複習一下管線中的部分座標變換流程。

model
view
projection
齊次除法+裁剪
屏幕映射
模型空間
世界空間
相機空間
裁剪空間
裁剪空間
NDC
屏幕空間
光柵化階段

注意projection矩陣在透視投影下是一個非線性變換矩陣,也就是裁剪空間、NDC、屏幕空間中的座標都是非線性空間下的座標。如果用非線性空間的座標來計算插值比s,使用s對頂點屬性插值就會得到錯誤的結果。

常見的例子就是屏幕上一條線段的中點,往往在實際的場景中並非是真正的中點。如下圖在投影平面上c是ab的中點,但實際上C在線段AB中的位置較靠近B。設頂點屬性IA=0,IB=1,我們希望插值所得的IC大概是0.7左右,但如果我們如果直接用線性插值來計算C的屬性就只能得到IC=0.5的錯誤結果。
在這裏插入圖片描述
透視校正插值使用線性的深度值非線性空間下的插值係數s來計算出線性空間下的插值係數t,並用t來對頂點屬性進行插值。說的明白點,在上圖中就相當於我們需要知道點A和點B距離投影平面的距離(線性深度),以及投影面上線段ac和bc的長度比(非線性空間下的插值係數,在上圖例子中就是1:1),然後我們就可以經過一系列數學推導得到真實場景中AC和BC長度的比值,通過這個比值我們就可以進行正確的線性插值得到C的屬性了。

【下面這段僅供參考,不能保證準確】
在光柵化階段中我們是如何訪問到線性空間下的深度值的呢?注意我們要的是線性的深度值,在光柵化階段,頂點座標的Z分量雖然記錄了頂點的深度值,但並不是一個線性的深度值,它維持了線性深度的大小關係來保證深度檢測正常,但對我們的透視矯正插值並沒有幫助。這裏我們就要注意頂點座標的w分量了。我們將相機空間的座標記爲(xview,yview,zview,wview),裁剪空間下的座標記爲(xclip,yclip,zclip,wclip),根據projection矩陣可知:wclip=-zview,相當於裁剪空間座標的w分量記錄了相機空間下頂點的深度值,而相機空間下的深度是線性的。wclip最重要的作用是在齊次除法中擔任分母,而在做完齊次除法後這個分量並沒有被丟棄,而是保留下來供透視校正插值使用。所以,在光柵化階段頂點座標的xyz分量都進入了非線性空間時,W分量仍保留了頂點的線性深度。
在這裏插入圖片描述
我們設點A的深度爲Z1,點B的深度爲Z2。C爲AB上的插值點,投影面上的插值比爲s。我們的目標根據Z1、Z2、s來求得線性空間下的插值比t,再根據t對頂點屬性進行插值,即存在一個函數f使得It=f(Z1,Z2,s,I1,I2)。

數學推導過程參考這篇博客。最後得出的插值公式如下:
在這裏插入圖片描述

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