2012-09-06 17 views
2

我最近一直在通過使用線性採樣方法而不是離散方法來優化高斯模糊着色器。基於可變權重量計算線性高斯模糊的偏移量

我讀了非常翔實的文章:

Efficient Gaussian Blur With Linear Sampling

二紋理像素的這種合併的情況下,我們必須調整座標的確定的距離的紋理像素#1中心座標應該等於texel#2的權重除以兩個權重的總和。在相同的樣式中,確定的座標距texel#2中心的距離應等於texel#1的權重除以兩個權重的總和。

雖然我理解這背後的邏輯,但我不確定他們是如何得到具有給定權重的偏移量的數字的。任何人都會友善地爲我闡明這一點,並解釋如何在統一的重量變量下計算正確的偏移量?

關於非硬編碼偏移量,我發現另一篇文章推薦了一種計算偏移量的方法,但是沒有針對可變數量的樣本發佈解決方案。我怎麼能做到這一點?

vec2 offsets[3]; 
offsets[0] = vec2(0.0, 0.0); 

offsets[1] = vec2(dFdx(gl_TexCoord[0].s), dFdy(gl_TexCoord[0].t)); 

offsets[2] = offsets[1] + offsets[1]; 

Fragment Offset

+0

對於任何人讀這篇文章,我終於摸索出自己的體重值,就像這樣: EXP( - (I * I)/(2 *西格瑪*西格瑪))/ (SQRT(2個*常量:: PI)*西格瑪); – Aequitas

回答

1

我對面的同一篇文章來了,發現它相當有用的爲好。的公式來計算權重和偏移在它被給出:

Formula http://www.rastergrid.com/blog/wp-content/uploads/2010/09/equation.png

作者通過在帕斯卡三角使用第12行到達權重。因此,例如第二偏移的計算方法是:

1.3846153846 = (1 * 792 + 2 * 495)/(792 + 495) 

第二權重的計算方法是:

0.1945945946 = (792 + 495)/4070 

我不知道你的意思是通過計算偏移量是什麼賦予統一權變量,但如果它是的幫助我在這篇文章的最後包含了一個C++程序,它爲pascal三角形中的任意一行輸出偏移和權重。

如果我理解你關於非硬編碼偏移量的問題,那麼你希望能夠在GLSL中實時計算偏移量?你可以通過移植下面的程序來做到這一點,但你仍然需要對二項係數進行硬編碼,或者即時計算這些係數。然而,這將是昂貴的,因爲它必須爲每個像素完成。我認爲一個更好的選擇是預先計算C中的偏移和權重(或者你使用的任何編程語言),然後將它們綁定到GLSL中的統一數組值。下面是我的真心GLSL片段:

uniform float offset[5]; 
    uniform float weight[5];" 
    uniform int numOffsets; 

你要替換「5」偏移的最大數量,你打算使用/重量,並設置numOffsets到您正在使用的數量特定的操作。

下面是輸出權重和偏移量的程序。 「coeffs」應該替換爲pascal表中所需行的二項式係數。這裏包括一個是從第22行

#include <iostream> 
#include <vector> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    float coeffs[] = { 705432, 646646, 497420, 319770, 170544, 74613, 26334, 7315, 1540, 231 }; 
    double total = coeffs[0]; 
    for (int i = 1; i < sizeof(coeffs)/sizeof(float); i++) 
    { 
     total += 2 * coeffs[i]; 
    } 
    vector<float> offsets; 
    vector<float> weights; 

    offsets.push_back(0); 
    weights.push_back(coeffs[0]/total); 

    for (int i = 1; i <= (sizeof(coeffs)/sizeof(float) - 1)/2; i++) 
    { 
     int index = (i - 1) * 2 + 1; 
     float weight = coeffs[index] + coeffs[index + 1]; 
     offsets.push_back((coeffs[index] * index + coeffs[index + 1] * (index + 1))/weight); 
     weights.push_back(weight/total); 
    } 

    for (int i = 0; i < offsets.size(); i++) 
    { 
     cout << offsets[i] << ", "; 
    } 
    cout << "\n"; 

    for (int i = 0; i < weights.size(); i++) 
    { 
     cout << weights[i] << ", "; 
    } 
    cout << "\n"; 
} 
+0

感謝Steve解決了我最初的困惑。請問爲什麼你選擇了第22排? – Aequitas

+0

我用第22行來試驗19抽頭濾波器。該文章使用第12行作爲9抽頭濾波器。一般來說,對於想要使用第(N + 3)行的N抽頭濾波器。 – DancesWithPixels

+0

只是想補充一點,我不確定一般的經驗法則是使用N + 3行,但如果您想忽略文章中提到的邊緣係數,那麼這就是遵循的方法。 – DancesWithPixels