简体   繁体   中英

How can i blur just the edges of an image in webgl shader

I am currently trying to Blur just the edges of an image with alpha with webgl but im not sure what is the best approach, i have tried to blur the entire image and then reapply the original rgb on top but obviously that didnt work.

Here is what im trying to achieve:
结果

and this is the original image:
原始图片

And here is the code that blurs the whole image instead:

function alphaTriangleBlur(radius) {
gl.alphaTriangleBlur = gl.alphaTriangleBlur || new Shader(null, '\
    uniform sampler2D texture;\
    uniform vec2 delta;\
    varying vec2 texCoord;\
    ' + randomShaderFunc + '\
    void main() {\
        vec4 color = vec4(0.0);\
        float total = 0.0;\
        \
        /* randomize the lookup values to hide the fixed number of samples */\
        float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\
        \
        for (float t = -30.0; t <= 30.0; t++) {\
            float percent = (t + offset - 0.5) / 30.0;\
            float weight = 1.0 - abs(percent);\
            vec4 sample = texture2D(texture, texCoord + delta * percent);\
            \
            /* switch to pre-multiplied alpha to correctly blur transparent images */\
            sample.rgb *= sample.a;\
            \
            color += sample * weight;\
            total += weight;\
        }\
        \
        gl_FragColor = color / total;\
        \
        /* switch back from pre-multiplied alpha */\
        gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\
    }\
');

simpleShader.call(this, gl.alphaTriangleBlur, {
    delta: [radius / this.width, 0]
});
simpleShader.call(this, gl.alphaTriangleBlur, {
    delta: [0, radius / this.height]
});

return this;
}

After several tries i found a solution! i have isolated the edges of the alpha and then used that edge to mask a box blur so that the blur affected just the edges, not sure it is the right way but it worked!

here the code:

function alphaTriangleBlur(radius) {
gl.alphaTriangleBlur = gl.alphaTriangleBlur || new Shader(null, '\
    uniform sampler2D texture;\
    uniform vec2 delta;\
    varying vec2 texCoord;\
    ' + randomShaderFunc + '\
    void main() {\
        vec4 color = vec4(0.0);\
        float total = 0.0;\
        \
        /* randomize the lookup values to hide the fixed number of samples */\
        float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\
        \
        for (float t = -50.0; t <= 50.0; t++) {\
            float percent = (t + offset - 0.5) / 50.0;\
            float weight = 1.0 - abs(percent);\
            vec4 og = texture2D(texture, texCoord);\
            vec4 sample = texture2D(texture, texCoord + delta * percent);\
            \
            /* switch to pre-multiplied alpha to correctly blur transparent images */\
            if(sample.a == 1.0){sample.rgb = og.rgb;}\
            else{sample.rgb *= sample.a;}\
            \
            color += sample * weight;\
            total += weight;\
        }\
        \
        gl_FragColor = color / total;\
        \
    }\
');
simpleShader.call(this, gl.alphaTriangleBlur, {
    delta: [radius / this.width, 0]
});
simpleShader.call(this, gl.alphaTriangleBlur, {
    delta: [0, radius / this.height]
});
simpleShader.call(this, gl.alphaTriangleBlur, {
    delta: [radius / this.width, 0]
});
simpleShader.call(this, gl.alphaTriangleBlur, {
    delta: [0, radius / this.height]
});

return this;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM