mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 10:49:59 +01:00
Finalizing implementation of chroma and luma key Transparency filters
This commit is contained in:
@@ -922,6 +922,22 @@ void ImGuiVisitor::visit (AlphaFilter& f)
|
|||||||
|
|
||||||
if ( m == AlphaFilter::ALPHA_CHROMAKEY || m == AlphaFilter::ALPHA_LUMAKEY)
|
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"];
|
float v = filter_parameters["Tolerance"];
|
||||||
if (ImGuiToolkit::IconButton(13, 14)) {
|
if (ImGuiToolkit::IconButton(13, 14)) {
|
||||||
v = 0.f;
|
v = 0.f;
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ void ImageFilter::setProgramParameter(const std::string &p, float value)
|
|||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
const char* ResampleFilter::factor_label[ResampleFilter::RESAMPLE_INVALID] = {
|
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_ = {
|
std::vector< FilteringProgram > ResampleFilter::programs_ = {
|
||||||
@@ -781,8 +781,8 @@ const char* AlphaFilter::operation_label[AlphaFilter::ALPHA_INVALID] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector< FilteringProgram > AlphaFilter::programs_ = {
|
std::vector< FilteringProgram > AlphaFilter::programs_ = {
|
||||||
FilteringProgram("Chromakey","shaders/filters/chromakey.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0}, { "Tolerance", 1.0} }),
|
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", "", { { "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} })
|
FilteringProgram("coloralpha","shaders/filters/coloralpha.glsl", "", { { "Red", 0.0}, { "Green", 1.0}, { "Blue", 0.0} })
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 Red;
|
||||||
uniform float Green;
|
uniform float Green;
|
||||||
uniform float Blue;
|
uniform float Blue;
|
||||||
|
uniform float Threshold;
|
||||||
uniform float Tolerance;
|
uniform float Tolerance;
|
||||||
|
|
||||||
//conversion between rgb and YUV
|
//conversion between rgb and YUV
|
||||||
@@ -22,19 +23,16 @@ mat4 RGBtoYUV = mat4(0.257, 0.439, -0.148, 0.0,
|
|||||||
0.0625, 0.500, 0.500, 1.0 );
|
0.0625, 0.500, 0.500, 1.0 );
|
||||||
|
|
||||||
// color to be removed
|
// color to be removed
|
||||||
vec4 chromaKey = vec4(Red, Green, Blue, 1);
|
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);
|
|
||||||
|
|
||||||
//compute color distance in the UV (CbCr, PbPr) plane
|
//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)
|
if (tmp < tol.x)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
else if (tmp < tol.y)
|
else if (tmp < tol.y)
|
||||||
@@ -43,36 +41,20 @@ float colorclose(vec3 yuv, vec3 keyYuv, vec2 tol)
|
|||||||
return 1.0;
|
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 )
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
||||||
{
|
{
|
||||||
vec4 texColor0 = texture(iChannel0, fragCoord.xy / iResolution.xy);
|
vec4 texColor0 = texture(iChannel0, fragCoord.xy / iResolution.xy);
|
||||||
|
|
||||||
//convert from RGB to YCvCr/YUV
|
//convert from RGB to YCvCr/YUV
|
||||||
// vec4 keyYUV = RGBtoYUV * chromaKey;
|
vec4 keyYUV = RGBtoYUV * chromaKey;
|
||||||
// vec4 yuv = RGBtoYUV * texColor0;
|
vec4 yuv = RGBtoYUV * texColor0;
|
||||||
// float mask = 1.0 - colorclose(yuv.rgb, keyYUV.rgb, maskRange);
|
|
||||||
// fragColor = max(texColor0 - mask * chromaKey, 0.0);
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
uniform float Threshold;
|
||||||
uniform float Tolerance;
|
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 = dot(RGB, vec3(0.299, 0.587, 0.114));
|
||||||
// float L = lightness( RGB );
|
// float L = lightness( RGB );
|
||||||
|
|
||||||
fragColor = vec4( RGB, smoothstep( 0.0, Tolerance, L ) );
|
fragColor = vec4( RGB, smoothstep( Threshold, Threshold + Tolerance * Tolerance, L ) );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user