Fast radial blur shader - GLSL

Viewed 424

I trying to a do fast radio blur using GLSL shader, here is my implementation:

  • Pass 1, calculate average color of 16 samples along the blur direction with unit step length.
  • Pass 2, calculate average color of 3 samples along the blur direction with 16 step length.

through this, I want to get the result of blur length of 48, but I get some artifact here left(my algotithm), right(bruteforce result)

I also tested the blur in the uniform direction, which also showed some artifacts, but less. Here is my shader code, you can test it on shadertoy:

// bruteforce mathod
#iChannel0 "file://E:/workspace/data/color_test.png"

const float u_sample_step = 1.0;
const int u_nsample = 48;
const vec2 u_center = vec2(0.5); // center in origional image, normalized to [0, 1]

void main() {
    vec2 coord = gl_FragCoord.xy / iResolution.xy;
    //vec2 cstep = u_sample_step/iResolution.xy * normalize(u_center - coord);
    vec2 cstep = u_sample_step/iResolution.xy * normalize(u_center - coord);
    vec4 color = vec4(0.0);
    for(int i=0; i<u_nsample; ++i) {
        color += texture2D(iChannel0, coord);
        coord += cstep;
    }
    gl_FragColor = color/float(u_nsample);
}

Pass 1 of the improved method:

#iChannel0 "test.png"

const float u_sample_step = 1.0;
const int u_nsample = 16;
const vec2 u_center = vec2(0.5); // center in origional image, normalized to [0, 1]

void main() {
    vec2 coord = gl_FragCoord.xy / iResolution.xy;
    //vec2 cstep = u_sample_step/iResolution.xy * normalize(u_center - coord);
    vec2 cstep = u_sample_step/iResolution.xy * normalize(u_center - coord);
    vec4 color = vec4(0.0);
    for(int i=0; i<u_nsample; ++i) {
        color += texture2D(iChannel0, coord);
        coord += cstep;
    }
    gl_FragColor = color/float(u_nsample);
}

Pass 2 of the improved method:

#iChannel0 "pass1.frag"

const float u_sample_step = 16.0;
const int u_nsample = 3;
const vec2 u_center = vec2(0.5); // center in origional image, normalized to [0, 1]

void main() {
    vec2 coord = gl_FragCoord.xy / iResolution.xy;
    //vec2 cstep = u_sample_step/iResolution.xy * normalize(u_center - coord);
    vec2 cstep = u_sample_step/iResolution.xy * normalize(u_center - coord);
    vec4 color = vec4(0.0);
    for(int i=0; i<u_nsample; ++i) {
        color += texture2D(iChannel0, coord);
        coord += cstep;
    }
    gl_FragColor = color/float(u_nsample);
}
0 Answers
Related