Merge¶
The Merge kernel combines two input images, srcA and srcB, using various blending modes controlled by the mode parameter. This allows for different compositing operations between the images.
Note
The max, min, and clamp functions for integer types are not supported by the BlinkScript effect in Nuke’s timeline if all the images have eAccessPoint data access. As a result, ternary operators are used in place of these functions to ensure compatibility and correct functionality.
#define kBlendPlus 1
#define kBlendDifference 2
#define kBlendDivide 3
#define kBlendMask 4
#define kBlendMax 5
#define kBlendMin 6
#define kBlendMinus 7
#define kBlendMultiply 8
#define kBlendOver 9
#define kBlendOverlay 10
#define kBlendAverage 11
kernel Merge : ImageComputationKernel<eComponentWise>
{
Image<eRead> srcB;
Image<eRead> srcA;
Image<eWrite> dst;
param:
int mode; // Set to a value between 1 - 11. See constants above.
void define() {
defineParam(mode, "mode", kBlendMask);
}
void process(int comp) {
// Check if the component index is valid for both srcA and srcB
const bool validA = comp < srcA.kComps;
const bool validB = comp < srcB.kComps;
ValueType(dst) dstValue = 0.0f;
ValueType(srcA) a = validA ? srcA() : 0.0f;
ValueType(srcB) b = validB ? srcB() : 0.0f;
// Perform blending based on the mode
if (mode == kBlendPlus) {
dstValue = a + b;
}
else if (mode == kBlendDifference) {
dstValue = fabs(a - b);
}
else if (mode == kBlendDivide) {
ValueType(srcB) eps = 0.000001f;
ValueType(srcB) denominator = (b > eps) ? b : eps;
dstValue = a / denominator;
}
else if (mode == kBlendMask) {
ValueType(srcA) srca = clamp(a, 0.0f, 1.0f);
dstValue = b * srca;
}
else if (mode == kBlendMax) {
dstValue = (a > b) ? a : b;
}
else if (mode == kBlendMin) {
dstValue = (a < b) ? a : b;
}
else if (mode == kBlendMinus) {
dstValue = a - b;
}
else if (mode == kBlendMultiply) {
dstValue = a * b;
}
else if (mode == kBlendOver) {
// Assuming 'a' is the alpha component if present
dstValue = a + b * (1.0f - a);
}
else if (mode == kBlendOverlay) {
dstValue = (a < 0.5f) ? (2.0f * a * b) : (1.0f - 2.0f * (1.0f - a) * (1.0f - b));
dstValue = clamp(dstValue, 0.0f, 1.0f);
}
else if (mode == kBlendAverage) {
dstValue = (a + b) * 0.5f;
}
else {
// Set destination to zero for invalid modes
dstValue = 0.0f;
}
dst() = dstValue;
}
};