-2
$\begingroup$

Crossposted here http://forum.lwjgl.org/index.php?topic=6724

Hello guys I am trying to blur image using fragment shader but it is not smooth.. I search the internet and I found similar problem... some one answer his question but unfortunately I cannot fallow it..

The question here are similar to my problem. this one https://stackoverflow.com/questions/33778381/how-to-blur-image-using-glsl-shader-without-squares and this one https://stackoverflow.com/questions/44829671/smooth-blur-gaussian-in-opengl-es-2-0

Now I am trying this code but I got error. cannot call a non-function

#version 120

uniform sampler2D sampler;
varying vec2 tex_coords;

vec4 funcBlurTexture() {
    float blur = 1.0/387.; //?? original settings: 2.0/720.; 
    //float blur = 1.0/1280.;

     vec4 sum = vec4(0.0);
     vec2 tc = tex_coords;

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

     float horizontalOffset = 2.0;
     float radius = 2.0;
     float verticalOffset = 2.0;
     float gaussFactorForOffset = 1.0;

     //Trying to use this
     for(horizontalOffset = -radius; horizontalOffset<radius; horizontalOffset  += step) {
        for(verticalOffset = -radius; verticalOffset<radius; verticalOffset += step) {
            sum += texture2D(sampler, tex_coords+vec2(horizontalOffset, verticalOffset))*gaussFactorForOffset(sqrt(horizontalOffset*horizontalOffset + verticalOffset*verticalOffset)/radius);
        }
     }

     /*
    //Old Code
     sum += texture2D(sampler, vec2(tc.x - 4.0*blur*hstep, tc.y)) * 0.0162162162;
     sum += texture2D(sampler, vec2(tc.x - 3.0*blur*hstep, tc.y)) * 0.0540540541;
     sum += texture2D(sampler, vec2(tc.x - 2.0*blur*hstep, tc.y)) * 0.1216216216;
     sum += texture2D(sampler, vec2(tc.x - 1.0*blur*hstep, tc.y)) * 0.1945945946;
     sum += texture2D(sampler, vec2(tc.x, tc.y)) * 0.2270270270;
     sum += texture2D(sampler, vec2(tc.x + 1.0*blur*hstep, tc.y)) * 0.1945945946;
     sum += texture2D(sampler, vec2(tc.x + 2.0*blur*hstep, tc.y)) * 0.1216216216; 
     sum += texture2D(sampler, vec2(tc.x + 3.0*blur*hstep, tc.y)) * 0.0540540541;
     sum += texture2D(sampler, vec2(tc.x + 4.0*blur*hstep, tc.y)) * 0.0162162162;
     */

        vec4 vColor = texture2D(sampler, tex_coords); 
        vec4 bluredTexture = vColor * vec4(sum.rgb, 1.0);
    return bluredTexture;
}

void main() {
    gl_FragColor = funcBlurTexture();
}

How to apply this code in my shader?

for(horizontalOffset = -radius; horizontalOffset<radius; horizontalOffset  += step) {
    for(verticalOffset = -radius; verticalOffset<radius; verticalOffset += step) {
        sum += texture2D(texture, textureCoordinate+vec2(horizontalOffset, verticalOffset))*gaussFactorForOffset(sqrt(horizontalOffset*horizontalOffset + verticalOffset*verticalOffset)/radius);
    }
}

Any Help?

$\endgroup$
  • $\begingroup$ Is it possible to post stacktrace here? $\endgroup$ – Drakonoved Apr 18 '18 at 19:00
1
$\begingroup$

It would be helpful if you posted some more information about what you're trying to do (rather than problem links) and some screenshots of what is actually happening. Being here I basically see "My code doesn't work, fix it.", which is not motivating to answer your question...

That being said, you calculate an offset for reading out from your texture.

texture2D(sampler, tex_coords+vec2(horizontalOffset, verticalOffset))

Texture coordinates are $u, v \in \left[0, 1\right]$, otherwise they will stay on the edge, border, go back to the opposite side or start from the opposide side again (depending on your set up). So this is offset is a problem at the borders in any case, but that is normal. If we now look at your offset

float radius = 2.0;
for(horizontalOffset = -radius; horizontalOffset<radius; horizontalOffset  += step)

So you start with an offset of -2.0, which far exceeds the texture coordinate interval and go up to 2.0 which again exceeds the interval. This is probably the biggest problem you have in your code, calculation wise.

Furthermore, you use a variable step to increase your horizontalOffset and your verticalOffset variables, but this step has never been created. This should not even compile.

Since your horizontalOffset and verticalOffsetare meant for the gaussian blur, I guess a new variable is needed.

Your next problem is, that iirc a gaussian blur should offset the texture coordinates, not the color. You multiply the readout color though, with your gaussFactorForOffset method, which may be wrong. In any case, you don't even have the method, and it is not a standard glsl method. Again this should not compile.


What you need is to think about what your kernel must look like. In a simple box filter, you would sample a texel and every neighbouring texel, giving you 9 values. You add up the 9 values, divide by 9 to normalize and write the output. Your gauss blur can work the same way, only that you have to properly weigh the individual values depending on their position. You can also sample more pixels, than the direct neighbour, say the second neighbour as well - this will give you a nicer blur but will also be a lot slower since you have to do more texture look ups.

In any case, start with hardcoding that, like you did in your old code.

In image processing, they also use these kernels, so you can look at them. The linked one would translate to your problem thus:

float verticalStep = 1/numberOfVerticalPixels;
float horizontalsteps = 1/numberOfHorizontalPixels; //these two variables you have to set yourself
//top row of kernel
sum += texture2D(sampler, vec2(tc.x - horizontalstep, tc.y - verticalStep)) * (1/16);
sum += texture2D(sampler, vec2(tc.x, tc.y - verticalStep)) * (1/8);
sum += texture2D(sampler, vec2(tc.x + horizontalstep, tc.y - verticalStep)) * (1/16);
//middle row
sum += texture2D(sampler, vec2(tc.x - horizontalstep, tc.y)) * (1/8);
sum += texture2D(sampler, vec2(tc.x, tc.y)) * (1/4);
sum += texture2D(sampler, vec2(tc.x + horizontalstep, tc.y)) * (1/8);
//bottom row
sum += texture2D(sampler, vec2(tc.x - horizontalstep, tc.y + verticalStep)) * (1/16);
sum += texture2D(sampler, vec2(tc.x, tc.y + verticalStep)) * (1/8);
sum += texture2D(sampler, vec2(tc.x + horizontalstep, tc.y + verticalStep)) * (1/16);
return sum;

Now once you get this to work, then you can start optimizing. and cleaning up your code.

$\endgroup$

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.