2015-05-19 49 views
0

所以我試圖實現基於this教程的高斯模糊着色器(用於練習)。我將他們的LWJGL代碼翻譯成JSFML代碼,這有點棘手。(J)SFML:高斯模糊着色器不工作

在我的實現中,只有背景精靈可見,鼠標周圍沒有模糊。

我的代碼如下,爲了提高可讀性而刪除了不相關的內容(如異常處理等)。

public class ShaderPractice { 

    private static final int RTSIZE = 1024; 
    private static float radius = 3; 
    private static float MAX_BLUR = 3; 

    public static void main(String[] args) { 
     RenderWindow rw = new RenderWindow(); 
     rw.create(new VideoMode(800, 600), "Gaussian Blur!"); 

     Texture t = new Texture(); 
     t.loadFromFile(Paths.get("textures/bg.jpg")); 

     Sprite bgSprite = new Sprite(t); 

     RenderTexture blurTargetA = new RenderTexture(); 
     blurTargetA.create(RTSIZE, RTSIZE); 

     RenderTexture blurTargetB = new RenderTexture(); 
     blurTargetB.create(RTSIZE, RTSIZE); 

     Shader blurShader = new Shader(); 
     blurShader.loadFromFile(Paths.get("src/shaderpractice/frag.glsl"), Shader.Type.FRAGMENT); 

     blurShader.setParameter("u_texture", t); 
     blurShader.setParameter("dir", new Vector2f(0, 0)); 
     blurShader.setParameter("resolution", RTSIZE); 
     blurShader.setParameter("radius", radius); 


     while (rw.isOpen()) { 

      Vector2f mousePos = rw.mapPixelToCoords(Mouse.getPosition()); 

      blurTargetA.clear(); 
      blurTargetA.draw(bgSprite); 
      blurTargetA.display(); 

      blurShader.setParameter("dir", new Vector2f(1, 0)); 

      float mouseXAmt = mousePos.x/rw.getSize().x; 
      blurShader.setParameter("radius", mouseXAmt * MAX_BLUR); 

      blurTargetB.clear(); 
      blurTargetB.draw(bgSprite, new RenderStates(blurShader)); 
      blurTargetB.display(); 

      blurShader.setParameter("dir", new Vector2f(0, 1)); 

      float mouseYAmt = (rw.getSize().y-mousePos.y-1)/rw.getSize().y; 
      blurShader.setParameter("radius", mouseYAmt * MAX_BLUR); 

      rw.draw(bgSprite, new RenderStates(blurShader)); 

      rw.display(); 

      for (Event event : rw.pollEvents()) { 
       if (event.type == Event.Type.CLOSED) { 
        rw.close(); 
       } 
      } 
     } 
    } 
} 

我的片段着色器如下(雖然我相信這是正確的,GLSL是從教程相同)

uniform sampler2D u_texture; 
uniform vec2 dir; 
uniform float resolution; 
uniform float radius; 

void main() { 

    // RGBA sum 
    vec4 sum = vec4(0.0); 

    vec2 tc = gl_TexCoord[0].xy; 

    float blur = radius/resolution; 

    float hstep = dir.x; 
    float vstep = dir.y; 

    //apply blurring, using a 9-tap filter with predefined gaussian weights 

    sum += texture2D(u_texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162; 
    sum += texture2D(u_texture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541; 
    sum += texture2D(u_texture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216; 
    sum += texture2D(u_texture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946; 

    sum += texture2D(u_texture, vec2(tc.x, tc.y)) * 0.2270270270; 

    sum += texture2D(u_texture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946; 
    sum += texture2D(u_texture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216; 
    sum += texture2D(u_texture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541; 
    sum += texture2D(u_texture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162; 

    gl_FragColor = vec4(sum.rgb, 1.0); 
} 

有人問之前,我只需要片段着色器這是因爲SFML在片段着色器中提供了正確的紋理座標。

我在做什麼錯誤?我懷疑這是我處理我的FBO的方式(在這種情況下是RenderTextures)。

回答

0

我注意到2個混亂點在你的程序


第一個是您在

blurShader.setParameter("dir", new Vector2f(0, 0)); 

但在着色器程序中設置dir(0.0, 0.0),你使用它作爲一個倍增因子:

float hstep = dir.x; 
float vstep = dir.y; 
... 
sum += texture2D(u_texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162; 
... 

顯然,4.0*blur*hstep的結果爲0。所以你只是對同一點進行抽樣。


第二件事是您正在使用高斯的方式。是不是這樣的:

for(int i=0;i<Num;i++) 
{ 
    for(int j=0;j<Num;j++) 
    { 
     sum += weight[i][j]*texture2D(texture,vec2(texture_coor[i][j].u,texture_coor[i][j].v)); 
    } 
} 

你只是在對角線上

採樣點