添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
#version 300 es
precision highp float;
in vec2 v_texCoord;
uniform sampler2D sTexture;
uniform sampler2D sPortraitTexture;
uniform highp vec2 inputSize;
layout(location = 0) out vec4 outColor;

float sdCircle(in vec2 p, in float r) {
    return length(p)-r;
}

void main() {
    float effectValue = 0.4;
    vec2 uv = v_texCoord;
    vec2 d = 1.0 / inputSize;
    float scale = (inputSize.x + inputSize.y)/1080.0;
    float kernel = floor(20.0 * scale * effectValue);
    vec4 maxCol = vec4(0.0);
    vec4 mask = texture(sPortraitTexture, uv);
    for(float x = -kernel;x<kernel;x++) {
        for(float y = -kernel;y<kernel;y++) {
            vec2 xy = vec2(x,y)/kernel;
            if(sdCircle(xy, 0.5 + effectValue * 0.2) < 0.0) {
                vec4 col = texture(sTexture, uv + d * vec2(x,y));
                maxCol = max(maxCol, col * mask.a);
            }
        }
    }
    outColor = maxCol;
}

有了光斑效果和抠出来的人像,可以使用 Blend 滤镜来验证一波:

//Blend
#version 300 es
precision highp float;
in vec2 v_texCoord;
uniform sampler2D sTexture;//做完光斑效果后的图像
uniform sampler2D sPortraitTexture;//mask 分割出来的人像
layout(location = 0) out vec4 outColor;

void main() {
    vec4 portraitCol = texture(sPortraitTexture, v_texCoord);
    vec4 srcCol = texture(sTexture, v_texCoord);
    outColor = mix(srcCol, portraitCol, portraitCol.a);
}

效果如下:

由2个原因导致的这个问题,一是算法抠图精确度不足,人像没有扣干净;二是融合的时候没有 alpha 预乘导致半透明的边缘发黑。针对这两个原因优化下我们的 blend shader :

#version 300 es
precision highp float;
in vec2 v_texCoord;
uniform sampler2D sTexture;//做完光斑和模糊效果后的图像
uniform sampler2D sPortraitTexture;/mask 分割出来的人像
layout(location = 0) out vec4 outColor;

void main() {
    vec4 portraitCol = texture(sPortraitTexture, v_texCoord);
    vec4 srcCol = texture(sTexture, v_texCoord);
    srcCol *= srcCol.a;// alpha 预乘
    portraitCol *= portraitCol.a;// alpha 预乘
    outColor = mix(srcCol, portraitCol, portraitCol.a);
    outColor.rgb /= max(0.000001, outColor.a);
}

来看最后的效果: