Shader中的片元著色器是如何對頂點著色器里傳入的uv,法線等做插值的?


一般來說,這不是在可編程著色器內進行的,而是屬於固定管線中的光柵化階段中實現。

例如 D3D11 Rasterizer Stage:

... During rasterization, each primitive is converted into pixels, while interpolating per-vertex values across each primitive. Rasterization includes clipping vertices to the view frustum, performing a divide by z to provide perspective, mapping primitives to a 2D viewport, and determining how to invoke the pixel shader...

著色器可以對個別頂點屬性設置插值方法 https://msdn.microsoft.com/en-us/library/windows/desktop/bb509668(v=vs.85).aspx,例如不使用預設的透示校正方法,而使用線性插值。


看架構的。

GCN架構(主機顯卡,主流 AMD 顯卡)下這部分是在 fragment shader 里做的,但是依然是對開發者不透明的。如果把編譯後的 fragment shader 彙編代碼弄出來就可以看到了。

GCN之前的架構都是在固定管線內做的。

補充一下:

(第10頁開始)

http://www.humus.name/Articles/Persson_LowlevelShaderOptimization.pdf

(第39頁開始)

https://michaldrobot.files.wordpress.com/2014/05/gcn_alu_opt_digitaldragons2014.pdf


這個插值不是片元著色器做的,而是在片元著色器前做的,這個過程是固定在硬體中的。

另外提一點:這個插值一般不是簡單的線性插值,而是加上了透視矯正的線性插值,直接線性插值會得到不正確的結果:

(圖片來源:https://en.wikipedia.org/wiki/File:Perspective_correct_texture_mapping.jpg)

中間是沒有加上透視矯正的結果,右邊是正確的結果。


一般來講,頂點屬性的插值在渲染流水線裡面,是在兩個著色器之間進行的,不是在片元著色器里進行的。你基本上只能控制它插或者不插。


2017.1.24,15:53更新:

做一些修正和補充(增補部分以黑色粗體高亮),感謝評論中幾位的補充,:

軟體演算法上就是直接的插值(線性一詞引起一些誤解,這裡略去,具體插值方式可以見其他一些答案)

硬體執行過程中可以注意的是:

  • 這個不一定是免費的,一些shader(是一些,不是全部)實現相當於是在fragment shader中做的插值計算
  • 一些較老的shader以及現在部分mobile gpu(目前高通的adreno主要還是如此)的上面會是以組為單位,應該是由於是vector base的alu計算硬體設計導致,就是比如

float2 uv0:TEXCOORD0;

float2 uv1:TEXCOORD1;

計算量是

float4: uv0:TEXCOORD0;

的兩倍。

可以通過一些pack來提升插值性能(總性能是否提升以最後測試為準, @馬應珍 和 @翟佳龍 提到的powervr上面的dependent texture read)

補充插值哪裡做的問題:

這個其他答案里提到,具體是這樣:理論上是不在fragment shader里做,但是實際硬體設計時候有可能放在fragment的計算單元里做,是一個理論和實際的差別。

之前項目里有一些依據理論信息做的優化但是達不到效果,就是因為這個放在fragment shader里做了。

實際項目中類似的情況遇到的比較多,比如某些硬體使用RGBA8 render target模擬R8或者其他奇怪格式的情況,造成顯存消耗不對勁。


在primitive裝配階段後送入光柵化模塊,光柵化結束後差值結果也就出來了,然後是PS階段。至於具體怎麼算的各個硬體廠商都有自己的手段,不一定一樣。


推薦閱讀:

實數中乘法不是加法的複合么?為什麼乘法與加法並列提及?
作為一個金融數學的研究生如何補數學?
為什麼在數學中,一些運算的逆運算比原運算難很多?
一個連續函數的問題?
工科生除了學習課內的《高等數學》,還可以做什麼提高自己的數學水平?

TAG:Unity遊戲引擎 | 高等數學 | 計算機圖形學 | 3D遊戲開發 | shader |