diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index 951e424..6ca8087 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -922,6 +922,22 @@ void ImGuiVisitor::visit (AlphaFilter& f) if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_LUMAKEY) { + float t = filter_parameters["Threshold"]; + if (ImGuiToolkit::IconButton(13, 14)) { + t = 0.f; + f.setProgramParameter("Threshold", t); + } + ImGui::SameLine(0, IMGUI_SAME_LINE); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + if (ImGui::SliderFloat( "Threshold", &t, 0.f, 1.f, "%.2f")) { + f.setProgramParameter("Threshold", t); + } + if (ImGui::IsItemDeactivatedAfterEdit()) { + oss << AlphaFilter::operation_label[ f.operation() ]; + oss << " : " << "Threshold" << " " << std::setprecision(3) << t; + Action::manager().store(oss.str()); + } + float v = filter_parameters["Tolerance"]; if (ImGuiToolkit::IconButton(13, 14)) { v = 0.f; diff --git a/ImageFilter.cpp b/ImageFilter.cpp index fb6cfb4..900b88f 100644 --- a/ImageFilter.cpp +++ b/ImageFilter.cpp @@ -477,7 +477,7 @@ void ImageFilter::setProgramParameter(const std::string &p, float value) //////////////////////////////////////// const char* ResampleFilter::factor_label[ResampleFilter::RESAMPLE_INVALID] = { - "Double x2", "Half 1/2", "Quarter 1/4" + "Double resolution", "Half resolution", "Quarter resolution" }; std::vector< FilteringProgram > ResampleFilter::programs_ = { @@ -781,8 +781,8 @@ const char* AlphaFilter::operation_label[AlphaFilter::ALPHA_INVALID] = { }; std::vector< FilteringProgram > AlphaFilter::programs_ = { - FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Tolerance", 1.0} }), - FilteringProgram("Lumakey", "shaders/filters/lumakey.glsl", "", { { "Tolerance", 0.5} }), + FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Threshold", 0.5}, { "Tolerance", 0.5} }), + FilteringProgram("Lumakey", "shaders/filters/lumakey.glsl", "", { { "Threshold", 0.5}, { "Tolerance", 0.5} } ), FilteringProgram("coloralpha","shaders/filters/coloralpha.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0} }) }; diff --git a/rsc/shaders/filters/chromakey.glsl b/rsc/shaders/filters/chromakey.glsl index 9563965..4daf959 100644 --- a/rsc/shaders/filters/chromakey.glsl +++ b/rsc/shaders/filters/chromakey.glsl @@ -13,6 +13,7 @@ green-ish look or are a bit transparent (hard to catch with a lot of movement) uniform float Red; uniform float Green; uniform float Blue; +uniform float Threshold; uniform float Tolerance; //conversion between rgb and YUV @@ -21,20 +22,17 @@ mat4 RGBtoYUV = mat4(0.257, 0.439, -0.148, 0.0, 0.098, -0.071, 0.439, 0.0, 0.0625, 0.500, 0.500, 1.0 ); -//color to be removed -vec4 chromaKey = vec4(Red, Green, Blue, 1); - -//range is used to decide the amount of color to be used from either foreground or background -//if the current distance from pixel color to chromaKey is smaller then maskRange.x we use background, -//if the current distance from pixel color to chromaKey is bigger then maskRange.y we use foreground, -//else, we blend them -//playing with this variable will decide how much the foreground and background blend together -vec2 maskRange = vec2(0.01, Tolerance * 0.5); +// color to be removed +vec4 chromaKey = vec4(Red, Green, Blue, 1.); //compute color distance in the UV (CbCr, PbPr) plane -float colorclose(vec3 yuv, vec3 keyYuv, vec2 tol) +float colordistance(vec3 yuv, vec3 keyYuv, vec2 tol) { - float tmp = sqrt(pow(keyYuv.g - yuv.g, 2.0) + pow(keyYuv.b - yuv.b, 2.0)); + // color distance in the UV (CbCr, PbPr) plane +// float tmp = sqrt(pow(keyYuv.y - yuv.y, 2.0) + pow(keyYuv.z - yuv.z, 2.0)); + vec2 dif = yuv.yz - keyYuv.yz; + float tmp = sqrt(dot(dif, dif)); + if (tmp < tol.x) return 0.0; else if (tmp < tol.y) @@ -43,36 +41,20 @@ float colorclose(vec3 yuv, vec3 keyYuv, vec2 tol) return 1.0; } -float alphachromakey(vec3 color, vec3 colorKey, float delta) -{ - // magic values - vec2 tol = vec2(0.5, 0.4*delta); - - //convert from RGB to YCvCr/YUV - vec4 keyYuv = RGBtoYUV * vec4(colorKey, 1.0); - vec4 yuv = RGBtoYUV * vec4(color, 1.0); - - // color distance in the UV (CbCr, PbPr) plane - vec2 dif = yuv.yz - keyYuv.yz; - float d = sqrt(dot(dif, dif)); - - // tolerance clamping - return max( (1.0 - step(d, tol.y)), step(tol.x, d) * (d - tol.x) / (tol.y - tol.x)); -} - - - void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec4 texColor0 = texture(iChannel0, fragCoord.xy / iResolution.xy); //convert from RGB to YCvCr/YUV -// vec4 keyYUV = RGBtoYUV * chromaKey; -// vec4 yuv = RGBtoYUV * texColor0; -// float mask = 1.0 - colorclose(yuv.rgb, keyYUV.rgb, maskRange); -// fragColor = max(texColor0 - mask * chromaKey, 0.0); + vec4 keyYUV = RGBtoYUV * chromaKey; + vec4 yuv = RGBtoYUV * texColor0; - float A = alphachromakey(texColor0.rgb, chromaKey.rgb, Tolerance); + float t = (1. - Tolerance) * 0.2; + float mask = 1.0 - colordistance(yuv.rgb, keyYUV.rgb, vec2(t, t + 0.2)); + vec4 col = max(texColor0 - mask * chromaKey, 0.0); - fragColor = vec4( texColor0.rgb, A ); + t = Threshold * Threshold * 0.2; + col.a -= 1.0 - colordistance(yuv.rgb, keyYUV.rgb, vec2(t, t + 0.25)); + + fragColor = col; } diff --git a/rsc/shaders/filters/lumakey.glsl b/rsc/shaders/filters/lumakey.glsl index 2dce34f..edca9d0 100644 --- a/rsc/shaders/filters/lumakey.glsl +++ b/rsc/shaders/filters/lumakey.glsl @@ -1,3 +1,4 @@ +uniform float Threshold; uniform float Tolerance; @@ -36,5 +37,5 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord ) float L = dot(RGB, vec3(0.299, 0.587, 0.114)); // float L = lightness( RGB ); - fragColor = vec4( RGB, smoothstep( 0.0, Tolerance, L ) ); + fragColor = vec4( RGB, smoothstep( Threshold, Threshold + Tolerance * Tolerance, L ) ); }