2
\$\begingroup\$

I've asked the same question on SO here and they suggested I should ask here instead.


I'm currently trying to create a gaussian blur shader, and while I've successfully created the blur effect my shader only renders the lower right quarter of my screen like the image shows:Screenshot of effect And just to make it clear; it has NOT re-scaled the image, it just doesn't render the rest of it.

Here's my shader code with comments of my thoughts:

Vertex (horizontal, vertical almost identical. See below)

#version 400

in vec2 a_texCoord0; //My tex coords

out vec2 blurTextureCoords[11]; //Sample 11px (i.e, 5 right 5 left of center)

uniform float u_width; //Width of the screen. Used to calculate pixel size

void main(void){
    gl_Position = vec4(a_texCoord0, 0.0, 1.0);
    vec2 centerTexCoords = a_texCoord0 * 0.5 + 0.5; //Maybe this is somehow wrong?
    float pixelSize = 1.0 / u_width; //This is kind of interesting, because my shader sometimes tells me that "no uniform value was found with name 'u_width', but it still seems to work as if I change the values manually (ex. set it to 1920) it still looks normal.

    for(int i=-5; i<=5; i++) {
        blurTextureCoords[i+5] = centerTexCoords + vec2(pixelSize * i, 0.0); //I also thought that it might be because I multiply a float with an integer, but if I do float(i) instead of just i it still looks the same.
    }

}

Fragment

#version 400
#ifdef GL_ES
precision mediump float;
#endif

in vec2 blurTextureCoords[11];

out vec4 out_colour;

uniform sampler2D u_texture;

void main(void){
    //The actual bluring
    out_colour = vec4(0.0);
    out_colour += texture(u_texture, blurTextureCoords[0]) * 0.0093;
    out_colour += texture(u_texture, blurTextureCoords[1]) * 0.028002;
    out_colour += texture(u_texture, blurTextureCoords[2]) * 0.065984;
    out_colour += texture(u_texture, blurTextureCoords[3]) * 0.121703;
    out_colour += texture(u_texture, blurTextureCoords[4]) * 0.175713;
    out_colour += texture(u_texture, blurTextureCoords[5]) * 0.198596;
    out_colour += texture(u_texture, blurTextureCoords[6]) * 0.175713;
    out_colour += texture(u_texture, blurTextureCoords[7]) * 0.121703;
    out_colour += texture(u_texture, blurTextureCoords[8]) * 0.065984;
    out_colour += texture(u_texture, blurTextureCoords[9]) * 0.028002;
    out_colour += texture(u_texture, blurTextureCoords[10]) * 0.0093;
}

Additional code

Creating a shader:

//I also have one for the vertical shader, it's almost exactly the same.
horizontalShader = new ShaderProgram(
    Gdx.files.internal("graphics/shaders/post-processing/blur/horizontalBlur.vert"),
    Gdx.files.internal("graphics/shaders/post-processing/blur/blur.frag"));
horizontalShader.pedantic = false;
horizontalShader.begin();
horizontalShader.setUniformf("u_width", Gdx.graphics.getWidth());
horizontalShader.end();

if (horizontalShader.getLog().length() != 0) {
    System.out.println("Horizontal shader! \n" + horizontalShader.getLog());
}

Rendering to FBO then to screen:

// Horozontal blur
horizontalFBO.begin();
spriteBatch.begin();
spriteBatch.setShader(horizontalShader);
background_image.draw(spriteBatch);
spriteBatch.end();
horizontalFBO.end();

// Vertical blur
verticalFBO.begin();
spriteBatch.begin();
spriteBatch.setShader(verticalShader);
spriteBatch.draw(horizontalFBO.getColorBufferTexture(), 0, 0);
spriteBatch.end();
verticalFBO.end();

// Normal FBO (screen)
spriteBatch.begin();
spriteBatch.setShader(null);
spriteBatch.draw(verticalFBO.getColorBufferTexture(), 0, 0);
spriteBatch.end();

Additional info

I use two FBOs, but it seems that those are not the root of the problem, as the problem still persists if I just render directly to the screen using these shaders.

I have two vertex shaders, one for the horizontal and one for the vertical blur. The only difference is the uniform name u_width becomes u_height and the blurTextureCoords[i+5] = centerTexCoords + vec2(pixelSize * i, 0.0); becomes blurTextureCoords[i+5] = centerTexCoords + vec2(0.0, pixelSize * i);

\$\endgroup\$
1
\$\begingroup\$

The screen coords go from {-1,-1} to {1,1} but you are most likely feeding it {0,0} to {1,1} - hence the fact that only one-quarter of the screen gets rendered.

So just to be clear - point {0,0} is not the top-left (or bottom-left, depending on your co-ordinate system) point; it's the center.

This also explains the texture coord tranformation that you are querying:

vec2 centerTexCoords = a_texCoord0 * 0.5 + 0.5; //Maybe this is somehow wrong?

This transformation maps position coords of {-1,-1 ... 1,1} to texture coords of {0,0 ... 1,1}, and is therefore correct.

\$\endgroup\$
  • \$\begingroup\$ This was what some other people told me as well, but I'm unsure on how to change this (or compensate for it) in LibGDX. Any solution or possibly a link? \$\endgroup\$ – Charanor May 3 '16 at 20:14
  • \$\begingroup\$ @Charanor - I would imagine that one of the SpriteBatch.Draw overloads would do it: libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/… - alternatively change it in your shader, e.g using a_texCoord0 * 2 - 1. \$\endgroup\$ – Maximus Minimus May 3 '16 at 20:23
  • \$\begingroup\$ So I changed the "centerTexCoords" to what you suggested, and that kind of "stretched" the edges of the image instead. I also tried just using "a_texCoord0" instead of "centerTexCoords" in my calculations, which resuted in the entire image being drawn, but at 1/8th of the size (still in the lower right corner). \$\endgroup\$ – Charanor May 3 '16 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.