File: //opt/resolve/Developer/Fusion Fuse/Example 4 MultiPixel Process.fuse
--[[--
Multi Process Pixel.fuse
--]]--
FuRegisterClass("Ex4MultiPxl", CT_Tool, {
REGS_Category = "Fuses\\Examples",
REGS_Name = "Ex4 MultiPixel",
REGS_OpIconString = "MltP",
REGS_OpDescription = "Multi-threaded pixel operations fuse",
})
function Create()
InOperation = self:AddInput("Operation", "Operation", {
LINKID_DataType = "Number",
INPID_InputControl = "MultiButtonControl",
INP_Default = 0.0,
{ MBTNC_AddButton = "Min", MBTNCD_ButtonWidth = 0.1, },
{ MBTNC_AddButton = "Max", MBTNCD_ButtonWidth = 0.2, },
{ MBTNC_AddButton = "Add", MBTNCD_ButtonWidth = 0.3, },
{ MBTNC_AddButton = "Variables", MBTNCD_ButtonWidth = 0.4, },
{ MBTNC_AddButton = "Copy RGBA To Aux", MBTNCD_ButtonWidth = 0.4, },
})
InImage1 = self:AddInput("Input 1", "Input1", {
LINKID_DataType = "Image",
LINK_Main = 1,
})
InImage2 = self:AddInput("Input 2", "Input2", {
LINKID_DataType = "Image",
LINK_Main = 2,
INP_Required = false,
})
OutImage = self:AddOutput("Output", "Output", {
LINKID_DataType = "Image",
LINK_Main = 1,
})
end
-- Function table for operations; p1 is a pixel from image1 and p2 is a pixel from image 2
op_funcs =
{
[1] = function(x,y,p1,p2) -- min
p1.R = math.min(p1.R, p2.R)
p1.G = math.min(p1.G, p2.G)
p1.B = math.min(p1.B, p2.B)
p1.A = math.min(p1.A, p2.A)
return p1
end,
[2] = function(x,y,p1,p2) -- max
p1.R = math.max(p1.R, p2.R)
p1.G = math.max(p1.G, p2.G)
p1.B = math.max(p1.B, p2.B)
p1.A = math.max(p1.A, p2.A)
return p1
end,
[3] = function(x,y,p1,p2) -- add
p1.R = p1.R + p2.R
p1.G = p1.G + p2.G
p1.B = p1.B + p2.B
p1.A = p1.A + p2.A
return p1
end,
[4] = function(x,y,p1,p2) -- Variables. any number of variables can be named and passed to the function
p1.R = gain * (p1.R - p2.R)
p1.G = p1.G - p2.G - bright
p1.B = var_C * (p1.B - p2.B)
p1.A = p1.A - p2.A
return p1
end,
-- Copy Img2 RGB to Background and Normals Aux channels of img1
-- These are the all the channels available:
-- R, G, B, A, BgR, BgG, BgB, BgA, Z, Coverage, ObjectID, MaterialID, U, V, W, NX, NY, NZ,
-- VectX, VectY, BackVectX, BackVectY, DisparityX, DisparityY, PositionX, PositionY, PositionZ
[5] = function(x,y,p1,p2)
p1.R = p1.R
p1.G = p1.G
p1.B = p1.B
p1.A = p1.A
p1.BgR = p2.R
p1.BgG = p2.G
p1.BgB = p2.B
p1.BgA = p2.A
return p1
end,
}
function Process(req)
local img1 = InImage1:GetValue(req)
local img2 = InImage2:GetValue(req)
local operation = InOperation:GetValue(req).Value+1
if img2 == nil then
img2 = img1
end
--This creates an image with 4 extra channels for function 5
local imgattrs = {
IMG_Document = self.Comp,
{ IMG_Channel = "Red", },
{ IMG_Channel = "Green", },
{ IMG_Channel = "Blue", },
{ IMG_Channel = "Alpha", },
{ IMG_Channel = "BgRed", },
{ IMG_Channel = "BgGreen", },
{ IMG_Channel = "BgBlue", },
{ IMG_Channel = "BgAlpha", },
IMG_Width = img1.Width,
IMG_Height = img1.Height,
IMG_XScale = img1.XAspect,
IMG_YScale = img1.YAspect,
IMAT_OriginalWidth = img1.realwidth,
IMAT_OriginalHeight = img1.realheight,
IMG_Quality = not req:IsQuick(),
IMG_MotionBlurQuality = not req:IsNoMotionBlur(),
}
if not req:IsStampOnly() then
imgattrs.IMG_ProxyScale = 1
end
if SourceDepth ~= 0 then
imgattrs.IMG_Depth = SourceDepth
end
local out = Image(imgattrs)
local func = op_funcs[operation] -- get pointer to the function from the table
-- Must have a valid operation function, and images must be same dimensions
if func and (img1.Width == img2.Width) and (img1.Height == img2.Height) then
out = Image({IMG_Like = img1})
out:MultiProcessPixels(nil, { gain = 2.0, bright = -0.3, var_C = 1.5 }, 0,0, img1.Width, img1.Height, img1, img2, func)
-- Note any variable names can be used and passed to the function, These { gain = 2.0, bright = -0.3, var_C = 1.5 } are used in Function 4
end
OutImage:Set(req, out)
end