How can I implement a GREAT blur?

Started by
3 comments, last by TheChubu 8 years, 3 months ago

I wanted a blur like this:

nkOL6Nt.png

But I have this(lol):

XiepS7t.png

I made the first one in Photoshop, hoping I could achieve something similar in-game. Here is my fragment shader(using radius 5.0):


//"in" attributes from our vertex shader
varying vec4 vColor;
varying vec2 vTexCoord;

//declare uniforms
uniform sampler2D u_texture;
uniform float resolution;
uniform float radius;
uniform vec2 dir;

void main() {
	vec4 sum = vec4(0.0);

    //our original texcoord for this fragment
    vec2 tc = vTexCoord;

    //the amount to blur, i.e. how far off center to sample from
    //1.0 -> blur by one pixel
    //2.0 -> blur by two pixels, etc.
    float blur = radius/resolution;

    //the direction of our blur
    //(1.0, 0.0) -> x-axis blur
    //(0.0, 1.0) -> y-axis blur
    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 = vColor * vec4(sum.rgba);
}

How can I decrappify it? Is it too much performance drawback? I'm actually planning to render a blurred scene a single time, cache it and then later apply a mask on which area to render blurred and unblurred. It will be used while sniper is aiming, I guess it would look cooler than just plain black.

Game I'm making - GANGFORT, Google Play, iTunes

Advertisement

Your offsets are too big. Thats why you get those artifacts.

I suggest you read this:

https://software.intel.com/en-us/blogs/2014/07/15/an-investigation-of-fast-real-time-gpu-based-image-blur-algorithms

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

I tried a blur recently (horizontal/vertical split Gaussian) and ended up with a similar effect to your second picture even when I tried with very small offsets. I wonder if there is something else to it e.g. how the texture has been setup.

That link TheChubu posted is worth checking out.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

Thanks, I will check it out. Now I'm wondering, how can these values be too big if I copied them from another tutorial. Are kernel weights const or do they depend on something, like image size?

Game I'm making - GANGFORT, Google Play, iTunes


Thanks, I will check it out. Now I'm wondering, how can these values be too big if I copied them from another tutorial. Are kernel weights const or do they depend on something, like image size?
Not the weights. The offsets you sample at.

Are you sure you're passing the correct "resolution" parameter for both vertical (height) and horizontal (width) passes? Are you sure youre switching the directions right?

Although you should also check the weights are ok (normalized and all).

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

This topic is closed to new replies.

Advertisement