1. 程式人生 > >WebGL 著色器偏導數dFdx和dFdy介紹

WebGL 著色器偏導數dFdx和dFdy介紹

本文適合對webgl、計算機圖形學、前端視覺化感興趣的讀者。

偏導數函式(HLSL中的ddx和ddy,GLSL中的dFdx和dFdy)是片元著色器中的一個用於計算任何變數基於螢幕空間座標的變化率的指令(函式)。在WebGL中,使用的是dFdx和dFdy,還有另外一個函式fwidth = dFdx + dFdy。

偏導數計算

在三角形柵格化期間,GPU會同時跑片元著色器的多個例項,但並不是一個pixel一個pixel去執行的,而是將其組織在2x2的一組pixels塊中並行執行。偏導數就是通過畫素塊中的變數的差值(變化率)而計算出來的。dFdx表示的是畫素塊中右邊畫素的值減去素塊中左邊畫素的值,而dFdy表示的是下面畫素的值減去上面畫素的值。如下圖所示,圖中顯示的是渲染的螢幕畫素,圖中紅色區域是一個畫素塊,p(x,y)表示在螢幕空間座標系中座標(x,y)的片元(畫素)上的某一個變數,圖中顯示了dFdx和dFdy的計算過程。

偏導數計算

偏導數函式可以用於片元著色器中的任何變數。對於向量和矩陣型別的變數,該函式會計算變數的每一個元素的偏導數。

偏導數函式是紋理mipmaps實現的基礎,也能實現一系列演算法和效果,特別是哪些依賴於螢幕空間座標的(比如渲染統一線寬的線框參考我的另外一篇文章:https://www.jianshu.com/p/1a0979a2d972)。

偏導數和mipmaps

Mipmaps用於計算紋理的一些列的子圖,每個子圖都比前一個的尺寸縮小了2倍。 他們用於在紋理縮小(紋理對映到比自身尺寸小的表面)的時候的去鋸齒。
Mipmaps 對於紋理快取的一致性也很重要,在遍歷一個三角形(的片元)的時候,它會強制獲取一個最近的畫素比例:這個比例保證三角形上的一個畫素儘量對應紋理上的一個畫素。 Mipmaps是可以同時視覺化效果和效能的少數技術之一。
在紋理取樣過程中使用偏導數來選擇最佳的 mipmap 級數。紋理座標在螢幕空間中的變化率作為選擇mimmap級數的依據,變化率越大,mimap級數越大,反之越小。

面的法線向量計算(flat shader)

偏導數函式可以用來在片元著色器中計算當前面(三角形)的法線向量。當前片元的世界座標系的水平偏導數和垂直偏導數是兩個三角形表面上的兩個向量,它們的叉乘結果是一個垂直於表面的向量,該向量的歸一化結果就是面的法線向量。需要特別注意的是兩個向量的叉乘的順序。下面是GLSL中通過鏡頭座標系中座標計算面法線向量的程式碼:

normalize(  cross(dFdx(pos),  dFdy(pos))  );

關於偏導數函式的應用之一可以參考 “WebGL 單通道wireframe渲染”,更多應用將在後續介紹。

參考文件
http://www.aclockworkberry.com/shader-derivative-functions/#footnote_3_1104

歡迎關注公眾號“ITman彪叔”。彪叔,擁有10多年開發經驗,現任公司系統架構師、技術總監、技術培訓師、職業規劃師。熟悉Java、JavaScript。在計算機圖形學、WebGL、前端視覺化方面有深入研究。對程式設計師思維能力訓練和培訓、程式設計師職業規劃和程式設計師理財投資有濃厚興趣。

ITman彪叔公