SFML community forums

Help => Graphics => Topic started by: tetra on May 19, 2015, 08:36:10 am

Title: Can someone help on how to use this guassian blur shader?
Post by: tetra on May 19, 2015, 08:36:10 am
I'm using this tutorial: https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson5#Overview

However, it's using LWJGL, and I'm using (J)SFML.

I know RenderTextures are FBO's, so that's not the problem, but I am having a little bit of a problem translating the code to SFML.

The code I have now:

~see below post for edited code~

All my shaders and textures are being loaded correctly, and I'm calling create() after I initialize them, with a size of 1024 (my screen size is 800x600).

Here's my fragment shader:

Code: [Select]
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);
}

When I launch the program, it just displays the background sprite. What am I doing wrong here?
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: Nexus on May 19, 2015, 10:47:24 am
You're only setting half of the shader's uniforms.

And setActive() is not needed, see documentation (http://www.sfml-dev.org/documentation/2.2/classsf_1_1RenderTexture.php#a5da95ecdbce615a80bb78399012508cf):
Quote
This function makes the render-texture's context current for future OpenGL rendering operations (so you shouldn't care about it if you're not doing direct OpenGL stuff).
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: tetra on May 19, 2015, 07:43:27 pm
I'm sorry, I forgot to include a few lines  before the rendering code, that I initalize the variables first:

Code: [Select]
                blurShader.setParameter("dir", new Vector2f(0, 0));
        blurShader.setParameter("resolution", RTSIZE);
        blurShader.setParameter("radius", radius);
       

where RTSIZE is 1024 and radius is 3.
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: tetra on May 19, 2015, 07:45:10 pm
Here's the code in its entirety, for more context:

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();
        try {
            t.loadFromFile(Paths.get("textures/bg.jpg"));
        } catch (IOException ex) {
        }
        Sprite bgSprite = new Sprite(t);

        RenderTexture blurTargetA = new RenderTexture();
        try {
            blurTargetA.create(RTSIZE, RTSIZE);
        } catch (TextureCreationException ex) {
        }
       
        RenderTexture blurTargetB = new RenderTexture();
        try {
            blurTargetB.create(RTSIZE, RTSIZE);
        } catch (TextureCreationException ex) {
        }
       
        Shader blurShader = new Shader();
        try {
            blurShader.loadFromFile(Paths.get("src/shaderpractice/frag.glsl"), Shader.Type.FRAGMENT);
        } catch (IOException | ShaderSourceException ex) {
        }
       
        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();
                }
            }
        }
    }
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: dabbertorres on May 20, 2015, 12:19:15 am
All your drawing to the window is the bgSprite, why would you expect anything else?

You're not drawing the results of drawing to the RenderTexture's to the window, is what I mean.
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: tetra on May 20, 2015, 12:48:10 am
Thank you for replying, I understand my problem better now.
Could you please tell me how to render those render textures to the window?
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: Nexus on May 20, 2015, 01:05:21 am
Using a sprite:
RenderTexture rt = ...;
Sprite sprite = ...;
sprite.setTexture(rt.getTexture());

// draw sprite as usual
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: tetra on May 20, 2015, 01:13:43 am
Alright! Would I use two sprites for this since there are two render textures?
Title: Re: Can someone help on how to use this guassian blur shader?
Post by: dabbertorres on May 20, 2015, 02:02:58 am
If you want a Sprite that keeps the original texture, then yes, I would use a second Sprite.