precision highp float; varying vec2 uv0; uniform sampler2D inputImageTexture; uniform sampler2D smoothMapTexturex; uniform float inputEdgeSmooth; uniform float inputSpill; uniform float widthOffset; uniform float heightOffset; uniform float enable_reverse; float getGaussianWeight(float x, float sigma) { return exp(-0.5 * x * x / (sigma * sigma)); } float normpdf(in float x, in float sigma) { return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma; } vec3 rgb_2_yuv(vec3 rgb) { highp vec3 yuv; yuv.x = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b; yuv.y = -0.14710802 * rgb.r + -0.28880402 * rgb.g + 0.435912 * rgb.b + 0.5; yuv.z = 0.61477697 * rgb.r -0.514799 * rgb.g - 0.099978 * rgb.b + 0.5; return yuv; } vec3 yuv_2_rgb(vec3 yuv) { mediump vec3 rgb; rgb.r = yuv.x + 1.14 * yuv.z - 0.57; rgb.g = yuv.x - 0.395 * yuv.y - 0.581 * yuv.z + 0.488; rgb.b = yuv.x + 2.032 * yuv.y - 1.016; return rgb; } vec3 rgb_2_hsv(vec3 c){ vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),d / (q.x + e),q.x); } vec3 hsv_2_rgb(vec3 c) { vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); return c.z * mix(vec3(1.0), rgb, c.y); } float calDis(vec3 rgb, float c) { float max_ = max(rgb.r, rgb.b); float min_ = min(rgb.r, rgb.b); return clamp(rgb.g - ((max_ - min_) * c * max_ + min_), 0.0, 1.0); } float mod_h(float h) { float h_ = h; if (h > 1.0) { h_ = h - 1.0; } else if (h < 0.0) { h_ = h + 1.0; } return h_; } vec4 processColor(vec4 rgba, vec4 bg_color, float alpha, float inputspill) { vec4 fixColor = rgba; const float EPS = 0.001; float weight = 1.0; fixColor.rgb = mix(fixColor.rgb, rgba.rgb, weight); rgba.rgb = fixColor.rgb; vec3 yuv_base = rgb_2_yuv(fixColor.rgb); yuv_base.y = 0.5; yuv_base.z = 0.5; vec3 fixColor_base = yuv_2_rgb(yuv_base); fixColor_base.rgb = clamp(fixColor_base.rgb, 0.0, 1.0); vec3 hsv = rgb_2_hsv(fixColor.rgb); vec3 hsv_bg = rgb_2_hsv(bg_color.rgb); float d_ = 0.02; float h = hsv.x; float h_bg = hsv_bg.x; if (h < 0.33333 + d_ && h > 0.33333 - d_) { h = 0.33333 - d_; } else if(h >= 0.33333 + d_) { h = h - d_ * 2.0; } if (h_bg < 0.33333 + d_ && h_bg > 0.33333 - d_) { h_bg = 0.33333 - d_; } else if(h_bg >= 0.33333 + d_) { h_bg = h_bg - d_ * 2.0; } float h_round = clamp(float(int(hsv_bg.x * 3.0 + 0.5)) / 3.0, 0.0, 1.0); float h_weight = min(abs(h - h_bg), 1.0 - 2.0 * d_ - abs(h - h_bg)); if (inputspill > EPS) { float h_weight_base = 1.0 - clamp((h_weight - 0.1) * 12.0, 0.0, 1.0); fixColor_base.rgb = mix(rgba.rgb, fixColor_base.rgb, h_weight_base); } else { fixColor_base.rgb = rgba.rgb; } float h_offset = min(abs(h_round - 0.33333), 1.0 - abs(h_round - 0.33333)); float flag = 1.0; if (hsv_bg.x > 0.33333 && hsv_bg.x < 0.83333) { flag = -1.0; } hsv.x = mod_h(hsv.x + flag * h_offset); vec3 fixColor_ = hsv_2_rgb(hsv); hsv_bg.x = mod_h(hsv_bg.x + flag * h_offset); vec3 selectedColour_ = hsv_2_rgb(hsv_bg); vec3 yuv = rgb_2_yuv(fixColor_.rgb); vec3 yuv_b = rgb_2_yuv(selectedColour_.rgb); float s_c = sqrt(pow(yuv.y - 0.5, 2.0)+pow(yuv.z - 0.5, 2.0)); float s_c_b = sqrt(pow(yuv_b.y - 0.5, 2.0)+pow(yuv_b.z - 0.5, 2.0)); float s = clamp(0.66 - 5.0 * s_c, 0.0, 1.0); float spill_ = inputspill - 0.25; float A_color = 1.0 - calDis(fixColor_, 1.0 - spill_ * (1.0 + s)) / max(0.01, calDis(selectedColour_, 1.0)); A_color = max(A_color, alpha / 3.0); A_color = clamp(A_color, 0.0001, 1.0); fixColor.rgb = (fixColor_ - (1.0 - A_color) * selectedColour_) / A_color; float maxrb = max(fixColor.r, fixColor.b); float minrb = min(fixColor.r, fixColor.b); fixColor.g = mix(fixColor.g, min(fixColor.g, (maxrb - minrb) * 0.9 * maxrb + minrb), inputspill); fixColor.rgb = clamp(fixColor.rgb, 0.0, 1.0); vec3 fixYUV = rgb_2_yuv(fixColor.rgb); float weight_y = min(1.0 - alpha, min(weight, 1.0 - A_color)); float kuv = clamp(s_c * 10.0, 0.0, 1.0); kuv = (1.0 - A_color) * kuv; kuv = mix(kuv, 1.0 - clamp((h_weight - 0.3) * 10.0, 0.0, 1.0), 1.0 - clamp((hsv.z-0.05)*2.0,0.0, 1.0)); fixYUV.x = fixYUV.x * weight_y + (1.0 - weight_y) * yuv.x; fixYUV.y = fixYUV.y * (1.0 - kuv) + kuv * 0.5; fixYUV.z = fixYUV.z * (1.0 - kuv) + kuv * 0.5; fixColor.rgb = yuv_2_rgb(fixYUV); fixColor.rgb = clamp(fixColor.rgb, 0.0, 1.0); hsv = rgb_2_hsv(fixColor.rgb); hsv.x = mod_h(hsv.x - flag * h_offset); fixColor.rgb = hsv_2_rgb(hsv); fixColor.rgb = mix(fixColor.rgb, fixColor_base.rgb, (1.0 - min(1.0, 2.5 * inputspill))); fixColor.rgb = mix(rgba.rgb, fixColor.rgb, clamp(s_c_b * 10.0, 0.0, 1.0)); return fixColor; } void main() { const float EPS = 0.001; vec4 rgba = texture2D(inputImageTexture, uv0); float alpha = texture2D(smoothMapTexturex, uv0).x; float alpha_ori = rgba.r; if (inputEdgeSmooth > EPS) { float alpha_ = 0.0; float L = min(1.0 / widthOffset, 1.0 / heightOffset) * 0.03; int r = 21;//int(inputEdgeSmooth * L); int kernel_size = r * 2 + 1; float weight = 0.0; float gamma = 1.4; for (int i = kernel_size - 1; i >= 0; i--) { vec2 offset= vec2(0.0, heightOffset * float(i - kernel_size / 2)); vec2 coordinate = uv0 + offset * 2. * inputEdgeSmooth; if (inputEdgeSmooth < .2) { if (i > 23 || i < 19) continue; coordinate = uv0 + offset * 8. * inputEdgeSmooth; } coordinate = clamp(coordinate, 0.0, 1.0); float pt_alpha = texture2D(smoothMapTexturex, coordinate).x; float w = normpdf(abs(float(i - kernel_size / 2)) / float(r) * 15., 4.); alpha_ += pow(pt_alpha, gamma) * w; weight += w; } alpha_ = clamp(alpha_ / weight, 0., 1.); alpha = pow(alpha_, 1. / gamma); } if (inputSpill > EPS) { rgba = processColor(rgba, vec4(0.0,0.0,0.0,1.0), alpha, inputSpill); } // gl_FragColor = rgba * alpha; // alpha = max(alpha, alpha_ori); gl_FragColor = vec4(alpha, 0, 0, 1); // gl_FragColor *= alpha_ori; if (enable_reverse > 0.5) gl_FragColor = vec4(vec3(1.0) - gl_FragColor.xyz, gl_FragColor.a); }