2010-12-04 176 views
6

我正在嘗試爲iPad編寫模糊着色器。我有它的工作,但我對結果並不滿意。當幀模糊率很高時,幀模糊不清,模糊看起來像是廢話。OpenGL ES 2.0片段着色器模糊速度慢,質量低

關於如何改善事情的任何想法?

一些樣本輸出:

alt text

uniform sampler2D texture; 
varying mediump vec2 fragTexCoord; 
varying mediump vec3 eyespaceNormal; 

varying highp float blurAmount; 

void main(void) 
{ 
    highp vec2 gaussFilter[7]; 
    gaussFilter[0] = vec2(-3.0, 0.015625); 
    gaussFilter[1] = vec2(-2.0, 0.09375); 
    gaussFilter[2] = vec2(-1.0, 0.234375); 
    gaussFilter[3] = vec2(0.0, 0.3125); 
    gaussFilter[4] = vec2(1.0, 0.234375); 
    gaussFilter[5] = vec2(2.0, 0.09375); 
    gaussFilter[6] = vec2(3.0, 0.015625); 

    highp float blurSize = blurAmount * 1.0; 

    ///////////////////////////////////////////////// 
    // 7x1 gaussian blur fragment shader 
    ///////////////////////////////////////////////// 

    highp vec4 color = vec4(0,0,0,1); 

    for(int i = 0; i < 7; i++) 
    { 
     color += texture2D(texture, vec2(fragTexCoord.x+gaussFilter[i].x*blurSize, fragTexCoord.y+gaussFilter[i].x*blurSize))*gaussFilter[i].y; 
    } 

    gl_FragColor = color; 
} 

編輯: 一個盒子模糊可能是要走的路。 這裏是着色器的盒子模糊版本:

highp vec4 color = vec4(0,0,0,1); 

color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 4.0*blurAmount)) * 0.05; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 3.0*blurAmount)) * 0.09; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - 2.0*blurAmount)) * 0.12; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y - blurAmount)) * 0.15; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y)) * 0.16; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + blurAmount)) * 0.15; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 2.0*blurAmount)) * 0.12; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 3.0*blurAmount)) * 0.09; 
color += texture2D(texture, vec2(fragTexCoord.x, fragTexCoord.y + 4.0*blurAmount)) * 0.05; 

gl_FragColor = color; 

這裏是箱模糊輸出(注意:這只是一個水平模糊,但它可能會爲我想要的東西是不夠的): alt text

回答

10

該着色器需要運行兩次爲它工作,你叫什麼blurSize應該是vec2和該值應該是vec2(0, 1.0/height)垂直模糊和vec2(1.0/width, 0)的水平模糊。

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=240334

背後做了兩遍模糊的想法是,這將大大減少紋理查找的數量,並希望增加的速度。內核大小爲7x7的兩遍模糊將需要14次紋理查找,但是如果在嵌套循環中完成,則需要執行49次紋理查找。

+0

是的,我認爲這是我調整代碼的麻煩。謝謝。我認爲我並不需要一個完整的高斯來達到我的目的,所以簡單的盒子模糊效果可能會更好,速度更快。 – Brian 2010-12-04 22:09:55

1

這是不清楚你的代碼到底在做什麼。您正在使用建議2D濾鏡的texture2D。然而你的卷積矩陣有一個維度,你只循環一次。我可能是錯的,但看起來你正在對角地應用模糊。如果它的意圖是2D過濾器,則需要分別用於x和y的兩個(嵌套)循環來覆蓋2D區域。

而關於變量blurSize - 它的名字有點誤導。模糊的大小取決於您的卷積矩陣。你的是7個像素寬。這決定了尺寸。這個變量更像是模糊的「強度」,它只能消除卷積矩陣的影響。如果賦予太高的價值,會出現文物。

我不是專家,除了「hello world」mandelbrot之外沒有寫過任何像素着色器。如果我沒有錯,比模糊着色器是最糟糕的加速之一。我看到的大多數實時模糊是box-blurs。嘗試從這裏移植一些代碼:gameDev thread

+0

我決定嘗試一個框模糊。似乎工作得很好,但我還沒有在我的iPad上嘗試過,看看它是否足夠快,但看起來不錯。我會在上面的答案中發佈代碼。謝謝 – Brian 2010-12-04 22:02:07