Index: source/blender/makesdna/DNA_node_types.h =================================================================== --- source/blender/makesdna/DNA_node_types.h (revision 51103) +++ source/blender/makesdna/DNA_node_types.h (working copy) @@ -686,6 +686,7 @@ typedef struct NodeKeyingData { float screen_balance; + float screen_subtract; float despill_factor; float despill_balance; int edge_kernel_radius; Index: source/blender/compositor/nodes/COM_KeyingNode.h =================================================================== --- source/blender/compositor/nodes/COM_KeyingNode.h (revision 51103) +++ source/blender/compositor/nodes/COM_KeyingNode.h (working copy) @@ -36,6 +36,8 @@ OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance); OutputSocket *setupFeather(ExecutionSystem *graph, CompositorContext *context, OutputSocket *featherInput, int falloff, int distance); + OutputSocket *setupScreenSubtract(ExecutionSystem *graph, OutputSocket *key, OutputSocket *subtractInput, + OutputSocket *inputScreen, float factor); OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputSrceen, float factor, float colorBalance); OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance, Index: source/blender/compositor/nodes/COM_KeyingNode.cpp =================================================================== --- source/blender/compositor/nodes/COM_KeyingNode.cpp (revision 51103) +++ source/blender/compositor/nodes/COM_KeyingNode.cpp (working copy) @@ -31,11 +31,14 @@ #include "COM_KeyingClipOperation.h" #include "COM_MathBaseOperation.h" +#include "COM_MixSubtractOperation.h" +#include "COM_MixDivideOperation.h" #include "COM_SeparateChannelOperation.h" #include "COM_CombineChannelsOperation.h" #include "COM_ConvertRGBToYCCOperation.h" #include "COM_ConvertYCCToRGBOperation.h" +#include "COM_ConvertKeyToPremulOperation.h" #include "COM_SetValueOperation.h" #include "COM_DilateErodeOperation.h" @@ -186,6 +189,47 @@ return operationy->getOutputSocket(); } +OutputSocket *KeyingNode::setupScreenSubtract(ExecutionSystem *graph, OutputSocket *key, OutputSocket *subtractInput, + OutputSocket *inputScreen, float factor) +{ + SetValueOperation *one = new SetValueOperation(); + SetValueOperation *factorOperation = new SetValueOperation(); + MathSubtractOperation *invertOperation = new MathSubtractOperation(); + MixSubtractOperation *subtractOperation = new MixSubtractOperation(); + MixBaseOperation *mixOperation = new MixBaseOperation(); + MixDivideOperation *unpremultOperation = new MixDivideOperation(); + ConvertKeyToPremulOperation *premultOperation = new ConvertKeyToPremulOperation(); + one->setValue(1.0f); + factorOperation->setValue(factor); + + addLink(graph, one->getOutputSocket(), invertOperation->getInputSocket(0)); + addLink(graph, key, invertOperation->getInputSocket(1)); + + addLink(graph, invertOperation->getOutputSocket(), subtractOperation->getInputSocket(0)); + addLink(graph, subtractInput, subtractOperation->getInputSocket(1)); + addLink(graph, inputScreen, subtractOperation->getInputSocket(2)); + + addLink(graph, one->getOutputSocket(), unpremultOperation->getInputSocket(0)); + addLink(graph, subtractOperation->getOutputSocket(), unpremultOperation->getInputSocket(1)); + addLink(graph, key, unpremultOperation->getInputSocket(2)); + + addLink(graph, unpremultOperation->getOutputSocket(), premultOperation->getInputSocket(0)); + + addLink(graph, factorOperation->getOutputSocket(), mixOperation->getInputSocket(0)); + addLink(graph, subtractInput, mixOperation->getInputSocket(1)); + addLink(graph, premultOperation->getOutputSocket(), mixOperation->getInputSocket(2)); + + graph->addOperation(one); + graph->addOperation(factorOperation); + graph->addOperation(invertOperation); + graph->addOperation(subtractOperation); + graph->addOperation(mixOperation); + graph->addOperation(unpremultOperation); + graph->addOperation(premultOperation); + + return mixOperation->getOutputSocket(); +} + OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputScreen, float factor, float colorBalance) { @@ -326,6 +370,13 @@ postprocessedImage = alphaOperation->getOutputSocket(); + /* subtract screen from image */ + if (keying_data->screen_subtract > 0.0f) { + postprocessedImage = setupScreenSubtract(graph, keyingOperation->getOutputSocket(), postprocessedImage, + keyingOperation->getInputSocket(1)->getConnection()->getFromSocket(), + keying_data->screen_subtract); + } + /* despill output image */ if (keying_data->despill_factor > 0.0f) { postprocessedImage = setupDespill(graph, postprocessedImage, Index: source/blender/makesrna/intern/rna_nodetree.c =================================================================== --- source/blender/makesrna/intern/rna_nodetree.c (revision 51103) +++ source/blender/makesrna/intern/rna_nodetree.c (working copy) @@ -3758,6 +3758,12 @@ RNA_def_property_ui_text(prop, "Screen Balance", "Balance between two non-primary channels primary channel is comparing against"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "screen_subtract", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "screen_subtract"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Screen Subtract", "Factor of the background subtraction process"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "despill_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "despill_factor"); RNA_def_property_range(prop, 0.0f, 1.0f); Index: source/blender/nodes/composite/nodes/node_composite_keying.c =================================================================== --- source/blender/nodes/composite/nodes/node_composite_keying.c (revision 51103) +++ source/blender/nodes/composite/nodes/node_composite_keying.c (working copy) @@ -74,6 +74,7 @@ data = MEM_callocN(sizeof(NodeKeyingData), "node keying data"); data->screen_balance = 0.5f; + data->screen_subtract = 1.0f; data->despill_balance = 0.5f; data->despill_factor = 1.0f; data->edge_kernel_radius = 3; Index: source/blender/editors/space_node/drawnode.c =================================================================== --- source/blender/editors/space_node/drawnode.c (revision 51103) +++ source/blender/editors/space_node/drawnode.c (working copy) @@ -2599,6 +2599,7 @@ uiItemR(layout, ptr, "blur_pre", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "screen_balance", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "screen_subtract", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "despill_factor", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "despill_balance", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "edge_kernel_radius", 0, NULL, ICON_NONE);