Add mask controls to the chroma key node

This commit is contained in:
Thomas Wilshaw
2022-05-03 22:50:59 +01:00
parent 5d0e90e6e4
commit a508bd8cad
3 changed files with 67 additions and 15 deletions
+18 -5
View File
@@ -26,6 +26,10 @@ const QString ChromaKeyNode::kColorInput = QStringLiteral("color_key");
const QString ChromaKeyNode::kMaskOnlyInput = QStringLiteral("mask_only_in");
const QString ChromaKeyNode::kUpperToleranceInput = QStringLiteral("upper_tolerence_in");
const QString ChromaKeyNode::kLowerToleranceInput = QStringLiteral("lower_tolerence_in");
const QString ChromaKeyNode::kGarbageMatteInput = QStringLiteral("garbage_in");
const QString ChromaKeyNode::kCoreMatteInput = QStringLiteral("core_in");
const QString ChromaKeyNode::kShadowsInput = QStringLiteral("shadows_in");
const QString ChromaKeyNode::kHighlightsInput = QStringLiteral("highlights_in");
ChromaKeyNode::ChromaKeyNode()
{
@@ -37,6 +41,16 @@ ChromaKeyNode::ChromaKeyNode()
AddInput(kLowerToleranceInput, NodeValue::kFloat, 5.0);
SetInputProperty(kLowerToleranceInput, QStringLiteral("min"), 0.0);
AddInput(kGarbageMatteInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
AddInput(kCoreMatteInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
AddInput(kHighlightsInput, NodeValue::kFloat, 100.0f);
SetInputProperty(kHighlightsInput, QStringLiteral("min"), 0.0);
AddInput(kShadowsInput, NodeValue::kFloat, 100.0f);
SetInputProperty(kShadowsInput, QStringLiteral("min"), 0.0);
AddInput(kMaskOnlyInput, NodeValue::kBoolean, false);
SetEffectInput(kTextureInput);
@@ -66,12 +80,11 @@ void ChromaKeyNode::Retranslate()
{
super::Retranslate();
SetInputName(kTextureInput, tr("Input"));
//SetInputName(kGarbageMatteInput, tr("Garbage Matte"));
//SetInputName(kCoreMatteInput, tr("Core Matte"));
SetInputName(kGarbageMatteInput, tr("Garbage Matte"));
SetInputName(kCoreMatteInput, tr("Core Matte"));
SetInputName(kColorInput, tr("Key Color"));
//SetComboBoxStrings(kColorInput, {tr("Green"), tr("Blue")});
//SetInputName(kShadowsInput, tr("Shadows"));
//SetInputName(kHighlightsInput, tr("Highlights"));
SetInputName(kShadowsInput, tr("Shadows"));
SetInputName(kHighlightsInput, tr("Highlights"));
SetInputName(kUpperToleranceInput, tr("Upper Tolerance"));
SetInputName(kLowerToleranceInput, tr("Lower Tolerance"));
SetInputName(kMaskOnlyInput, tr("Show Mask Only"));
+4
View File
@@ -46,6 +46,10 @@ class ChromaKeyNode : public OCIOBaseNode {
static const QString kMaskOnlyInput;
static const QString kUpperToleranceInput;
static const QString kLowerToleranceInput;
static const QString kGarbageMatteInput;
static const QString kCoreMatteInput;
static const QString kShadowsInput;
static const QString kHighlightsInput;
private:
void GenerateProcessor();
+45 -10
View File
@@ -5,6 +5,14 @@ uniform bool mask_only_in;
uniform float upper_tolerence_in;
uniform float lower_tolerence_in;
uniform sampler2D garbage_in;
uniform sampler2D core_in;
uniform bool garbage_in_enabled;
uniform bool core_in_enabled;
uniform float highlights_in;
uniform float shadows_in;
// Main texture coordinate
in vec2 ove_texcoord;
@@ -38,11 +46,11 @@ vec4 CIExyz_to_Lab(vec4 CIE) {
}
float colorclose(vec4 col, vec4 key, float tola,float tolb) {
/*decides if a color is close to the specified hue*/
float temp = sqrt(((key.g-col.g)*(key.g-col.g))+((key.b-col.b)*(key.b-col.b)));
if (temp < tola) {return (0.0);}
if (temp < tolb) {return ((temp-tola)/(tolb-tola));}
return (1.0);
/*decides if a color is close to the specified hue*/
float temp = sqrt(((key.g-col.g)*(key.g-col.g))+((key.b-col.b)*(key.b-col.b)));
if (temp < tola) {return (0.0);}
if (temp < tolb) {return ((temp-tola)/(tolb-tola));}
return (1.0);
}
@@ -50,8 +58,13 @@ void main() {
vec4 col = texture(tex_in, ove_texcoord);
vec4 unassoc = col;
if (unassoc.a > 0) {
unassoc.rgb /= unassoc.a;
}
// Perform color conversion
vec4 cie_xyz = SceneLinearToCIEXYZ_d65(col);
vec4 cie_xyz = SceneLinearToCIEXYZ_d65(unassoc);
vec4 lab = CIExyz_to_Lab(cie_xyz);
vec4 cie_xyz_key = SceneLinearToCIEXYZ_d65(color_key);
@@ -59,12 +72,34 @@ void main() {
float mask = colorclose(lab, lab_key, lower_tolerence_in, upper_tolerence_in);
mask = clamp(mask, 0.0, 1.0);
if (garbage_in_enabled) {
// Force anything we want to remove to be 0.0
vec4 garbage = texture(garbage_in, ove_texcoord);
// Assumes garbage is achromatic
mask -= garbage.r;
mask = clamp(mask, 0.0, 1.0);
}
if (core_in_enabled) {
// Force anything we want to keep to be 1.0
vec3 core = texture(core_in, ove_texcoord).rgb;
// Assumes core is achromatic
mask += core.r;
mask = clamp(mask, 0.0, 1.0);
}
// Crush blacks and push whites
mask = shadows_in * 0.01 * (highlights_in * 0.01 * mask - 1.0) + 1.0;
mask = clamp(mask, 0.0, 1.0);
col.rgb *= mask;
col.w = mask;
if (!mask_only_in) {
frag_color = col;
} else {
frag_color = vec4(vec3(mask), 1.0);
}
frag_color = col;
} else {
frag_color = vec4(vec3(mask), 1.0);
}
}