2021.12.13
昨天跟一個哥們聊天講到面試圖形學過程當中有人問到什麼是雅克比矩陣微分;上網查了一下,雅克比矩陣微分是在微分場景下找到兩個微分空間基底的線性變換矩陣。
【切空間就能夠其理解爲微分空間】
切空間都是矢量空間,都有基底,因此這個線性變換就是矩陣。在歐氏空間子空間的開集上,切空間就是某個。
因此把Jacobian矩陣當作切空間之間的基底之間的線性變換,
而矩陣的行列式的值的幾何意義:是矩陣對應的線性變換先後的面積比。
這也是爲何積分中變換座標時前面會乘以一個Jacobian矩陣的行列式。
下面舉了個例子,對於機械臂來講若是每次都用xy的直角座標來表示整個過程位置比較麻煩,因此採用角度和臂長來表示比較容易。同時又知道二者之間轉化關係。那麼咱們問每次兩個角速度變化時,xy的變化速度是多少?這時候就能夠利用雅克比矩陣來計算每次角速度變化對xy的變化速率是多少。也便是由角速度的微分空間變換到了直角座標系的微分空間。
紋理映射一個須要處理的問題是紋理的抗鋸齒問題。
好比上圖將紋理貼到一個平面,當隨着觀察角度不一樣,會出現紋理的鋸齒現象。解決方案是使每一個像素不是點樣本,而是使用當前屏幕2d像素計算出覆蓋的紋理空間圖像面積中全部像素的平均值
那麼怎麼計算一個像素覆蓋多少紋理空間的面積?
一個像素所對應的紋理範圍稱爲像素的紋理空間覆蓋區,要計算這個覆蓋區是挺複雜的一個事情,由於這個物體的表面有很大關係,表面多是一個曲面。並且隨着觀察角度和位置不一樣,同一個屏幕像素的紋理空間覆蓋區是不同的。
上圖總能夠看到屏幕像素對應紋理空間不是一個矩形,而是不一樣的四邊形,可能仍是有曲率的。要計算這個曲面的覆蓋像素比較麻煩。
那麼這裏計算這個覆蓋區,即利用微分思想作一些近似。
下面有些繞,咱們能夠把屏幕的像素想象成一個微分單元,這個微分單元實際上對應咱們渲染物體表面的一個點,這個點會對應一個紋理座標。這裏要注意,雖然紋理座標咱們是在直角座標系下定義的,但實際上紋理空間並不必定是一個直角空間,可想象一個圖片貼到一個曲面上,確定是彎曲的,因此下圖中紋素的真正走向實際上是彎曲的線。因此從一個屏幕空間到一個紋素空間也不是線性的。好比看下圖
可是當對於屏幕像素這個極小的微分單元下咱們能夠認爲是線性的。這個映射過程就是uv左邊分別對屏幕的x方向和y方向求導數。那麼在該點處紋理座標分別投影在屏幕xy方向構成了一個平行四邊形。
即:
雅克比矩陣爲:
這時候的雅可比矩陣定義是屏幕空間的像素變化與紋理空間變化的線性變換。
更專業的幾何解釋是:
因此這時候要作紋理抗鋸齒就是在屏幕空間位置處的像素大小對應的紋理座標導數定義的平行四邊形輪廓範圍內的紋素顏色的平均值。
那麼接下來只要找出這個平行四邊形覆蓋的紋素便可。
這裏讓我想起glsl中的dFdx和dFdy兩個函數,就是用來計算一個量在此點的屏幕空間方向的導數。
固然硬件這裏的計算仍是利用屏幕像素來作微分單元進行的。
這裏可以計算,是由於GPU是以一個wrap來進行並行處理的,一個wrap來不一樣的顯卡架構上是不同的,有的是2x2的像素有的是32x32的像素。因此這裏的偏導數就是像素塊中變量的差值來計算出來的。dFdx表示的是像素塊中右邊像素的值減去素塊中左邊像素的值,而dFdy表示的是下面像素的值減去上面像素的值。
說到這裏到能夠考慮利用偏導數作一些圖像處理,好比對於地圖中某些要素在俯視圖下出現鋸齒問題,那麼在片元着色器下,能夠根據偏導數的大小決定是否繪製。
再好比焦散那篇文章中,文檔:WebGL 水波及焦散(刻蝕)的渲染總結.n...
根據兩個變量在偏導數上的乘積比來作一些決策:
如今再回到紋理採樣這個問題上,上面說到只要找到紋理空間那個平行四邊形的覆蓋區域就好了。可是即便是這個平行四邊形,仍然是極其昂貴的計算,因此在這個基礎上又作了一些近似。好比雙線性插值,實際上是利用紋理座標點的周圍的四個像素並根據必定的權重來計算顏色值。
可是即便是雙線性插值也是很昂貴的計算,須要一些硬件的支持。因此有的高性能系統有專門的紋理採樣硬件來支持。
雙線性插值是一種近似,因此有的時候並非很好。也就誕生了其餘的一些輔助的方法。好比mipmap和各向異性。(虎書中把這個查找過程稱爲濾波)
紋理挺坑的,說到這裏還要介紹一個紋理的透視插值問題。這問題我以前有了解過,可是看一些圖形庫好像也沒有專門處理這部份內容,不知道是否是硬件來處理了,因此沒有太多關注。
這個能夠看下面這篇文章,我先不肯定這個過程是圖形管線本身修復的仍是須要開發者來修復。貌似看到的各類圖形庫都沒有本身處理過這個問題。