In light of the Coronavirus crisis, please help make sure nothing stands in the way of social distancing in the VFX industry.

This petition asks the MPAA to act accordingly:


Sign the petition on Change.org

Be safe, everyone.

[RC] Vibrance Fuse

Where the future is being made, today.

Welcome to the WSL development corner!

In this forum, please post your development projects. You get kudos and feedback here.
Topics ideally have preset prefixes, and this is what they (might) mean:

  • [DEV] - very much work in progress, don't build a business on this, could go anywhere
  • [BETA] - should kinda do what it's supposed to do, please test, give feedback
  • [RC] - this may end up in Reactor soon, polishing up, now's the time for last minute thoughts
  • [ABD] - died a premature death, sadness, will not see the light of day ever (unless someone picks up the scraps)

Once a development project has been released (hurray), topics can be marked as - you guessed it - [RELEASED] :cheer:

Development topics only, please. For generic questions, how-to's, questions and inquiries about existing tools etc, please go to the appropriate other forums.
User avatar
intelligent machine
Fusionista
Posts: 509
Joined: Fri May 13, 2016 10:01 pm
Answers: 3
Location: Austin, Texas, USA
Real name: Sam Treadway
Been thanked: 13 times
Contact:

Re: [RC] Vibrance Fuse

#166

Post by intelligent machine » Thu Mar 26, 2020 12:08 pm

Shem Namo wrote:
Thu Mar 26, 2020 11:55 am
It's not working on my end for some reason.
I renamed it in the FuRegisterClass to match the file name: "Vibrance".

Added in 4 minutes 3 seconds:
In this version I added Clamping to some of the Vibrance methods for testing.

I may be a good idea in the future to add "Clamp" as an option.

For not I'm just using it for testing some ideas while keeping the output values between 0 and 1.
Code: [Select all] [Expand/Collapse] [Download] (Vibrance.fuse)
  1. FuRegisterClass("Vibrance", CT_Tool, {
  2.     REGS_Category = "Fuses\\Color",
  3.     REGS_OpIconString = "TNT",
  4.     REGS_OpDescription = "Vibrance",
  5.     REG_Version = 1.0,
  6.     REGS_Company = "Learn Now FX",
  7.     REGS_URL = "http://www.youtube.com/LearnNowFX",
  8. })
  9.  
  10.  
  11. VibranceParams = [[
  12.     float red;
  13.     float green;
  14.     float blue;
  15.     float method;
  16.     float vibrance;
  17.     float saturation;
  18.     float gain;
  19.     float gamma;
  20.     int unmult;
  21.     int invert;
  22.     float again;
  23.     int clip;
  24.     int srcCompOrder;
  25. ]]
  26.  
  27. VibranceKernel = [[
  28.     __KERNEL__ void VibranceKernel(__CONSTANTREF__ VibranceParams *params, __TEXTURE2D__ src, __TEXTURE2D_WRITE__ dst) {
  29.         DEFINE_KERNEL_ITERATORS_XY(x, y);
  30.         float4 col = _tex2DVecN(src, x, y, params->srcCompOrder);
  31.  
  32.         //Clamp
  33. //      col.x = _fmaxf(0, _fminf(1, col.x));
  34. //      col.y = _fmaxf(0, _fminf(1, col.y));
  35. //      col.z = _fmaxf(0, _fminf(1, col.z));
  36.  
  37.         // The Invert Control math goes here:
  38.         if (params->invert == 1) {
  39.             col.x = 1 - col.x;
  40.             col.y = 1 - col.y;
  41.             col.z = 1 - col.z;
  42.         }
  43.  
  44.  
  45.         // The Color Picker math goes here:
  46.         if (params->invert == 0) {
  47.             col.x *=  params->red;
  48.             col.y *=  params->green;
  49.             col.z *=  params->blue;
  50.         }
  51.  
  52.         if (params->invert == 1) {
  53.             float nRed = params->red + 0.0001f;
  54.             float nGreen = params->green + 0.0001f;
  55.             float nBlue = params->blue + 0.0001f;
  56.             col.x = powr(col.x, 1/nRed);
  57.             col.y = powr(col.y, 1/nGreen);
  58.             col.z = powr(col.z, 1/nBlue);
  59.         }
  60.  
  61.  
  62.         // The Gain control math goes here:
  63.         col.x *=  params->gain;
  64.         col.y *=  params->gain;
  65.         col.z *=  params->gain;
  66.  
  67.  
  68.         // The Gamma control math goes here:
  69.         col.x = powr(col.x, 1/_fmaxf(params->gamma, 0.01f));
  70.         col.y = powr(col.y, 1/_fmaxf(params->gamma, 0.01f));
  71.         col.z = powr(col.z, 1/_fmaxf(params->gamma, 0.01f));
  72.  
  73.  
  74.         // The UnMultiply math goes here:
  75.         float luma = col.x * 0.299f + col.y * 0.587f + col.z * 0.114f;
  76.         if (params->unmult == 1) {
  77.             col.w *= (luma + params->again);
  78.         }
  79.  
  80.  
  81.         //The Vibrance math goes here:
  82.         float cMax = _fmaxf(col.x, _fmaxf(col.y, col.z));  //find the strongest color
  83.         float cMin = _fminf(col.x, _fminf(col.y, col.z));  //find the weakest color
  84.         float cSat = cMax - cMin; //The diff of min and max color is the Saturation
  85.         float cAverage = (col.x + col.y + col.z) / 3.0f;
  86.         float vibrance = params->vibrance;
  87.         float scale = 1.0;
  88.                 //custom version - special treatemnt for reds
  89.         if (params->method == 0) {
  90.             scale = vibrance * (2 * (1 - cSat)); //Less Saturated given higher priority
  91.             if (cMax == col.x) { //special treatment when red is max
  92.                 scale = vibrance * (abs(col.y - col.z) / (cSat / cAverage)) * (1 - cSat);
  93.             }
  94.                     //Clamp
  95.             scale = _fminf(1, scale);
  96.                     //Lerp
  97.             col.x = (col.x - cMax) * scale + col.x;
  98.             col.y = (col.y - cMax) * scale + col.y;
  99.             col.z = (col.z - cMax) * scale + col.z;
  100.         }
  101.                 //Simple
  102.         if (params->method == 1) {
  103.             scale = vibrance * ( 0.25 * (1 - cAverage));
  104.                     //Clamp
  105. //          scale = _fminf(1, scale);
  106.                     //Lerp
  107.             col.x = (col.x - cMin) * scale + col.x;
  108.             col.y = (col.y - cMin) * scale + col.y;
  109.             col.z = (col.z - cMin) * scale + col.z;
  110.         }
  111.                 //complex
  112.         if (params->method == 2) {
  113.             scale = vibrance * (1.0 - (sign(vibrance) * cAverage));
  114.                     //Clamp
  115. //          scale = _fminf(1, scale);
  116.                     //Lerp
  117.             col.x = (col.x - cAverage) * scale + col.x;
  118.             col.y = (col.y - cAverage) * scale + col.y;
  119.             col.z = (col.z - cAverage) * scale + col.z;
  120.         }
  121.                 //pow version
  122.         if (params->method == 3) {
  123.             scale = 1.0 - powr(cSat, 1.0 - (1.0 - vibrance));
  124.                     //Clamp
  125.             scale = _fminf(1, scale);
  126.                     //Lerp
  127.             col.x = (col.x - cSat) * scale + col.x;
  128.             col.y = (col.y - cSat) * scale + col.y;
  129.             col.z = (col.z - cSat) * scale + col.z;
  130.            
  131.             //Clamp
  132.             col.x = _fmaxf(0, _fminf(1, col.x));
  133.             col.y = _fmaxf(0, _fminf(1, col.y));
  134.             col.z = _fmaxf(0, _fminf(1, col.z));
  135.         }
  136.  
  137.  
  138.         // The Saturation math goes here:
  139.         col.x = params->saturation * col.x + (1-params->saturation) * luma;
  140.         col.y = params->saturation * col.y + (1-params->saturation) * luma;
  141.         col.z = params->saturation * col.z + (1-params->saturation) * luma;
  142.  
  143.  
  144.         //the Clip negative Pixels math goes here:
  145.         if (params->clip == 1) {
  146.             if (col.x < 0) { col.x = 0; }
  147.             if (col.y < 0) { col.y = 0; }
  148.             if (col.z < 0) { col.z = 0; }
  149.         }
  150.  
  151.  
  152.         _tex2DVec4Write(dst, x, y, col);
  153.     }
  154. ]]
  155.  
  156. OpenDemoURL = [[
  157. -- Open a webpage window up using your default web browser
  158.     platform = (FuPLATFORM_WINDOWS and "Windows") or (FuPLATFORM_MAC and "Mac") or (FuPLATFORM_LINUX and "Linux")
  159.     function OpenURL(siteName, path)
  160.         if platform == "Windows" then
  161.             -- Running on Windows
  162.             command = "explorer \"" .. path .. "\""
  163.         elseif platform == "Mac" then
  164.             -- Running on Mac
  165.             command = "open \"" .. path .. "\" &"
  166.         elseif platform == "Linux" then
  167.             -- Running on Linux
  168.             command = "xdg-open \"" .. path .. "\" &"
  169.         else
  170.             print("[Error] There is an invalid Fusion platform detected")
  171.             return
  172.         end
  173.  
  174.         os.execute(command)
  175.         -- print("[Launch Command] ", command)
  176.         print("[Opening URL] [" .. siteName .. "] " .. path)
  177.     end
  178.  
  179.     OpenURL("Demo", "https://youtu.be/2XF8BsJ1J5o")
  180. ]]
  181.  
  182. function Create()
  183.     self:BeginControlNest("Color", "Color", true, {})
  184.         InColorR= self:AddInput("Red", "Red", {
  185.             ICS_Name            = "Color",
  186.             LINKID_DataType     = "Number",
  187.             INPID_InputControl  = "ColorControl",
  188.             INP_Default         = 1,
  189.             INP_MaxScale        = 1.0,
  190.             ICD_Center          = 1.0,
  191.             INP_DoNotifyChanged = true,
  192.             CLRC_ShowWheel      = False,
  193.             IC_ControlGroup     = 1,
  194.             IC_ControlID        = 0,
  195.             IC_Visible          = true,
  196.         })
  197.         InColorG = self:AddInput("Green", "Green", {
  198.             LINKID_DataType     = "Number",
  199.             INPID_InputControl  = "ColorControl",
  200.             INP_Default         = 1,
  201.             INP_DoNotifyChanged = true,
  202.             IC_ControlGroup     = 1,
  203.             IC_ControlID        = 1,
  204.         })
  205.         InColorB = self:AddInput("Blue", "Blue", {
  206.             LINKID_DataType     = "Number",
  207.             INPID_InputControl  = "ColorControl",
  208.             INP_Default         = 1,
  209.             INP_DoNotifyChanged = true,
  210.             IC_ControlGroup     = 1,
  211.             IC_ControlID        = 2,
  212.         })
  213.         InInvert = self:AddInput("Invert", "Invert", {
  214.             LINKID_DataType = "Number",
  215.             INPID_InputControl = "CheckboxControl",
  216.             INP_Integer = true,
  217.             ICD_Width = 0.5,
  218.             INP_Default = 0,
  219.         })  
  220.     self:EndControlNest()
  221.    
  222.     self:BeginControlNest("Intensity", "Intensity", true, {})
  223.         InVibranceMethod = self:AddInput("Vibrance Method", "VibranceMethod", {
  224.             LINKID_DataType = "Number",
  225.             INPID_InputControl = "ComboControl",
  226.             INP_MinScale = 0,
  227.             INP_MaxAllowed = 3,
  228.             INP_MinAllowed = 0,
  229.             INP_MaxAllowed = 3,
  230.             INP_Integer = true,
  231.             ICD_Width = 1.0,
  232.             CC_LabelPosition = "Horizontal",
  233.             INP_DoNotifyChanged = true,
  234.             { CCS_AddString = "Vibrant", },
  235.             { CCS_AddString = "Simple", },
  236.             { CCS_AddString = "Complex", },
  237.             { CCS_AddString = "Power", },
  238.         })
  239.         InVibrance = self:AddInput("Vibrance", "Vibrance", {
  240.             LINKID_DataType = "Number",
  241.             INPID_InputControl = "SliderControl",
  242.             INP_Default = 0,
  243.             INP_MinScale = 0,
  244.             INP_MaxScale = 3,
  245.             INP_Default = 1,
  246.         })
  247.         InSaturation = self:AddInput("Saturation", "Saturation", {
  248.             LINKID_DataType = "Number",
  249.             INPID_InputControl = "SliderControl",
  250.             INP_MinScale = 0,
  251.             INP_MaxScale = 2,
  252.             INP_Default = 1,
  253.         })
  254.         InGain = self:AddInput("Gain", "Gain", {
  255.             LINKID_DataType = "Number",
  256.             INPID_InputControl = "SliderControl",
  257.             INP_MinScale = 0,
  258.             INP_MaxScale = 5,
  259.             INP_Default = 1,
  260.         })
  261.         InGamma = self:AddInput("Gamma", "Gamma", {
  262.             LINKID_DataType = "Number",
  263.             INPID_InputControl = "SliderControl",
  264.             INP_MinScale = 0,
  265.             INP_MaxScale = 2,
  266.             INP_Default = 1,
  267.         })
  268.     self:EndControlNest()
  269.    
  270.     self:BeginControlNest("Alpha", "Alpha", true, {})
  271.         InUnMultiply = self:AddInput("UnMultiply", "UnMultiply", {
  272.             LINKID_DataType = "Number",
  273.             INPID_InputControl = "CheckboxControl",
  274.             INP_Integer = true,
  275.             INP_Default = 0,
  276.         })
  277.         InAlphaGain = self:AddInput("Alpha Gain", "Alpha Gain", {
  278.             LINKID_DataType = "Number",
  279.             INPID_InputControl = "SliderControl",
  280.             INP_MinScale = 0,
  281.             INP_MaxScale = 1,
  282.             INP_Default = 0,
  283.         })
  284.     self:EndControlNest()
  285.    
  286.     self:BeginControlNest("Advanced", "Advanced", false, {})
  287.         InDepth = self:AddInput("Depth", "Depth", {
  288.             LINKID_DataType = "Number",
  289.             INPID_InputControl = "ComboControl",
  290.             INP_Default = 2.0,
  291.             INP_Integer = true,
  292.             ICD_Width = 1.0,
  293.             CC_LabelPosition = "Vertical",
  294.             INP_DoNotifyChanged = true,
  295.             { CCS_AddString = "int8", },
  296.             { CCS_AddString = "int16", },
  297.             { CCS_AddString = "float 16", },
  298.             { CCS_AddString = "float 32", },
  299.         })
  300.         InClip = self:AddInput("Clip Negative Pixels", "Clip Negative Pixels", {
  301.             LINKID_DataType = "Number",
  302.             INPID_InputControl = "CheckboxControl",
  303.             INP_Integer = true,
  304.             ICD_Width = 1.0,
  305.             INP_Default = 1,
  306.         })
  307.         DemoButton = self:AddInput("Demo", "Demo", {
  308.             LINKS_Name = "Demo",
  309.             LINKID_DataType = "Number",
  310.             INPID_InputControl = "ButtonControl",
  311.             BTNCS_Execute = OpenDemoURL,
  312.         })
  313.     self:EndControlNest()
  314.    
  315.     InImage = self:AddInput("Image", "Image", {
  316.         LINKID_DataType = "Image",
  317.         LINK_Main = 1,
  318.         INP_AcceptsGPUImages = true,
  319.     })
  320.     OutImage = self:AddOutput("Output", "Output", {
  321.         LINKID_DataType = "Image",
  322.         LINK_Main = 1,
  323.     })
  324. end
  325.  
  326.  
  327. function Process(req)
  328.     local src = InImage:GetValue(req)
  329.     local depth = InDepth:GetValue(req).Value
  330.     local dst = Image{ IMG_Like = src, IMG_Depth = depth + 1, IMG_DeferAlloc = true }
  331.    
  332.     local node = DVIPComputeNode(req, "VibranceKernel", VibranceKernel, "VibranceParams", VibranceParams)
  333.     local params = node:GetParamBlock(VibranceParams)
  334.  
  335.     params.red = InColorR:GetValue(req).Value
  336.     params.green = InColorG:GetValue(req).Value
  337.     params.blue = InColorB:GetValue(req).Value
  338.     params.method = InVibranceMethod:GetValue(req).Value
  339.     params.vibrance = InVibrance:GetValue(req).Value
  340.     params.saturation = InSaturation:GetValue(req).Value
  341.     params.gain = InGain:GetValue(req).Value
  342.     params.gamma = InGamma:GetValue(req).Value
  343.     params.unmult = InUnMultiply:GetValue(req).Value
  344.     params.again = InAlphaGain:GetValue(req).Value
  345.     params.invert = InInvert:GetValue(req).Value
  346.     params.clip = InClip:GetValue(req).Value
  347.     params.srcCompOrder = src:IsMask() and 1 or 15
  348.  
  349.     node:SetParamBlock(params)
  350.  
  351.     node:AddInput("src", src)
  352.     node:AddOutput("dst", dst)
  353.  
  354.     local ok = node:RunSession(req)
  355.  
  356.     if not ok then
  357.         dst = nil
  358.     end
  359.        
  360.     OutImage:Set(req, dst)
  361. end

User avatar
Shem Namo
Fusionista
Posts: 349
Joined: Sun Oct 06, 2019 9:15 pm
Location: North Israel
Real name: David Kohen
Been thanked: 6 times

Re: [RC] Vibrance Fuse

#167

Post by Shem Namo » Thu Mar 26, 2020 12:34 pm

@intelligent machine ,
I'm still having trouble viewing the fuse.
I'm getting RT Kernel failed to build.

I'm just wondering are the // at line 105 and 115, supposed to be there?

It could be an issue with Notepad++, On my system it also changes the formatting when I paste it here on the forum.
Before posting any code here I use SciTe to fix the formatting issues.

Thanks again,

User avatar
intelligent machine
Fusionista
Posts: 509
Joined: Fri May 13, 2016 10:01 pm
Answers: 3
Location: Austin, Texas, USA
Real name: Sam Treadway
Been thanked: 13 times
Contact:

Re: [RC] Vibrance Fuse

#168

Post by intelligent machine » Thu Mar 26, 2020 12:37 pm

At the top of the code block is a download link. Try that.

User avatar
intelligent machine
Fusionista
Posts: 509
Joined: Fri May 13, 2016 10:01 pm
Answers: 3
Location: Austin, Texas, USA
Real name: Sam Treadway
Been thanked: 13 times
Contact:

Re: [RC] Vibrance Fuse

#169

Post by intelligent machine » Thu Mar 26, 2020 11:49 pm

Here's an update. Enjoy ;)

Depending on the tint applied, different modes may work better than others.
For instance, on grayscale images, when you are applying a tint and vibrance, the "Vibrant" mode treats color differently when the max is in the red channel.
Any undesirable effects will be noticeable mostly when invert is turned on and red is set to zero and green or blue is pushed up.

I've altered quite a bit of the code to get this to work.
The order in which the tint and invert are applied is important.
I've fixed the invert math to work properly with the alpha and the tint is now multiplied against the original color before adding it to the color.

With color images the different modes can produce drastically different looks that are all fun to play with.
This sample image is just a test using only the Vibrance feature. The mode names are temp. I'm sure we can come up with some cool names later:
Image

Image
Code: [Select all] [Expand/Collapse] [Download] (Vibrance.fuse)
  1. FuRegisterClass("Vibrance", CT_Tool, {
  2.     REGS_Category = "Fuses\\Color",
  3.     REGS_OpIconString = "TNT",
  4.     REGS_OpDescription = "Vibrance",
  5.     REG_Version = 1.0,
  6.     REGS_Company = "Learn Now FX",
  7.     REGS_URL = "http://www.youtube.com/LearnNowFX",
  8. })
  9.  
  10.  
  11. VibranceParams = [[
  12.     float red;
  13.     float green;
  14.     float blue;
  15.     float mode;
  16.     float vibrance;
  17.     float saturation;
  18.     float gain;
  19.     float gamma;
  20.     int unmult;
  21.     int invert;
  22.     float again;
  23.     int clip;
  24.     int srcCompOrder;
  25. ]]
  26.  
  27. VibranceKernel = [[
  28.     __KERNEL__ void VibranceKernel(__CONSTANTREF__ VibranceParams *params, __TEXTURE2D__ src, __TEXTURE2D_WRITE__ dst) {
  29.         DEFINE_KERNEL_ITERATORS_XY(x, y);
  30.         float4 col = _tex2DVecN(src, x, y, params->srcCompOrder);
  31.         float luma = col.x * 0.299f + col.y * 0.587f + col.z * 0.114f;
  32.         float vibrance = params->vibrance;
  33.  
  34.  
  35.         // UnMultiply math:
  36.         if (params->unmult == 1) {
  37.             col.w *= (luma + params->again);
  38.         }
  39.  
  40.  
  41.         // Invert Control math:
  42.         if (params->invert == 1) {
  43.             col.x = col.w * (1 - col.x);
  44.             col.y = col.w * (1 - col.y);
  45.             col.z = col.w * (1 - col.z);
  46.         }
  47.  
  48.  
  49.         // Color Picker math:
  50.         col.x += col.x * params->red;
  51.         col.y += col.y * params->green;
  52.         col.z += col.z * params->blue;
  53.  
  54.  
  55.         // The Gain control math goes here:
  56.         col.x *=  params->gain;
  57.         col.y *=  params->gain;
  58.         col.z *=  params->gain;
  59.  
  60.  
  61.         // The Gamma control math goes here:
  62.         col.x = powr(col.x, 1/_fmaxf(params->gamma, 0.01f));
  63.         col.y = powr(col.y, 1/_fmaxf(params->gamma, 0.01f));
  64.         col.z = powr(col.z, 1/_fmaxf(params->gamma, 0.01f));
  65.  
  66.  
  67.         // Vibrance math:
  68.         float cMax = _fmaxf(col.x, _fmaxf(col.y, col.z));  //find the strongest color
  69.         float cMin = _fminf(col.x, _fminf(col.y, col.z));  //find the weakest color
  70.         float cSat = cMax - cMin; //The diff of min and max color is the Saturation
  71.         float cAverage = (col.x + col.y + col.z) / 3.0f;
  72.         float scale = 1.0;
  73.                 //Vibrant
  74.         if (params->mode == 0) {
  75.             scale = vibrance * (2 * (1 - cSat)); //Less Saturated given higher priority
  76.             if (cMax == col.x) { //special treatment when red is max
  77.                 scale = vibrance * (abs(col.y - col.z) / (cSat / cAverage)) * (1 - cSat);
  78.             }
  79.                     //Clamp
  80.             scale = _fminf(1, scale);
  81.                     //Lerp
  82.             col.x = (col.x - cMax) * scale + col.x;
  83.             col.y = (col.y - cMax) * scale + col.y;
  84.             col.z = (col.z - cMax) * scale + col.z;
  85.         }
  86.                 //Simple
  87.         if (params->mode == 1) {
  88.             scale = vibrance * ( 0.25 * (1 - cAverage));
  89.                     //Lerp
  90.             col.x = (col.x - cMin) * scale + col.x;
  91.             col.y = (col.y - cMin) * scale + col.y;
  92.             col.z = (col.z - cMin) * scale + col.z;
  93.         }
  94.                 //Complex
  95.         if (params->mode == 2) {
  96.             scale = vibrance * (1.0 - (sign(vibrance) * cAverage));
  97.                     //Lerp
  98.             col.x = (col.x - cAverage) * scale + col.x;
  99.             col.y = (col.y - cAverage) * scale + col.y;
  100.             col.z = (col.z - cAverage) * scale + col.z;
  101.         }
  102.                 //Power
  103.         if (params->mode == 3) {
  104.             scale = vibrance * (1.0 - powr(cSat, 1 / (vibrance + 1.0f)));
  105.                     //Clamp
  106.             scale = _fminf(1, scale);
  107.                     //Lerp
  108.             col.x = (col.x - cSat) * scale + col.x;
  109.             col.y = (col.y - cSat) * scale + col.y;
  110.             col.z = (col.z - cSat) * scale + col.z;
  111.         }
  112.  
  113.  
  114.         // The Saturation math goes here:
  115.         col.x = params->saturation * col.x + (1-params->saturation) * luma;
  116.         col.y = params->saturation * col.y + (1-params->saturation) * luma;
  117.         col.z = params->saturation * col.z + (1-params->saturation) * luma;
  118.  
  119.  
  120.         //the Clip negative Pixels math goes here:
  121.         if (params->clip == 1) {
  122.             if (col.x < 0) { col.x = 0; }
  123.             if (col.y < 0) { col.y = 0; }
  124.             if (col.z < 0) { col.z = 0; }
  125.         }
  126.  
  127.  
  128.         _tex2DVec4Write(dst, x, y, col);
  129.     }
  130. ]]
  131.  
  132. OpenDemoURL = [[
  133. -- Open a webpage window up using your default web browser
  134.     platform = (FuPLATFORM_WINDOWS and "Windows") or (FuPLATFORM_MAC and "Mac") or (FuPLATFORM_LINUX and "Linux")
  135.     function OpenURL(siteName, path)
  136.         if platform == "Windows" then
  137.             -- Running on Windows
  138.             command = "explorer \"" .. path .. "\""
  139.         elseif platform == "Mac" then
  140.             -- Running on Mac
  141.             command = "open \"" .. path .. "\" &"
  142.         elseif platform == "Linux" then
  143.             -- Running on Linux
  144.             command = "xdg-open \"" .. path .. "\" &"
  145.         else
  146.             print("[Error] There is an invalid Fusion platform detected")
  147.             return
  148.         end
  149.  
  150.         os.execute(command)
  151.         -- print("[Launch Command] ", command)
  152.         print("[Opening URL] [" .. siteName .. "] " .. path)
  153.     end
  154.  
  155.     OpenURL("Demo", "https://youtu.be/2XF8BsJ1J5o")
  156. ]]
  157.  
  158. function Create()
  159.     self:BeginControlNest("Tint", "Tint", true, {})
  160.         InShowWheel = self:AddInput("Show Advanced", "ShowAdvanced", {
  161.             LINKID_DataType = "Number",
  162.             INPID_InputControl = "CheckboxControl",
  163.             INP_Integer = true,
  164.             ICD_Width = 0.5,
  165.             INP_Default = 0,
  166.             INP_External = false,
  167.             INP_DoNotifyChanged = true,
  168.         })
  169.         InColorR = self:AddInput("Red", "Red", {
  170.             ICS_Name            = "Color",
  171.             LINKID_DataType     = "Number",
  172.             INPID_InputControl  = "ColorControl",
  173.             INP_Default         = 0,
  174.             INP_MaxScale        = 1.0,
  175.             ICD_Center          = 1.0,
  176.             INP_DoNotifyChanged = true,
  177.             CLRC_ShowWheel      = false,
  178.             IC_ControlGroup     = 1,
  179.             IC_ControlID        = 0,
  180.             IC_Visible          = true,
  181.         })
  182.         InColorG = self:AddInput("Green", "Green", {
  183.             LINKID_DataType     = "Number",
  184.             INPID_InputControl  = "ColorControl",
  185.             INP_Default         = 0,
  186.             INP_DoNotifyChanged = true,
  187.             IC_ControlGroup     = 1,
  188.             IC_ControlID        = 1,
  189.         })
  190.         InColorB = self:AddInput("Blue", "Blue", {
  191.             LINKID_DataType     = "Number",
  192.             INPID_InputControl  = "ColorControl",
  193.             INP_Default         = 0,
  194.             INP_DoNotifyChanged = true,
  195.             IC_ControlGroup     = 1,
  196.             IC_ControlID        = 2,
  197.         })
  198.         InInvert = self:AddInput("Invert", "Invert", {
  199.             LINKID_DataType = "Number",
  200.             INPID_InputControl = "CheckboxControl",
  201.             INP_Integer = true,
  202.             ICD_Width = 0.5,
  203.             INP_Default = 0,
  204.         })  
  205.     self:EndControlNest()
  206.    
  207.     self:BeginControlNest("Intensity", "Intensity", true, {})
  208.         InVibranceMode = self:AddInput("Vibrance Mode", "VibranceMode", {
  209.             LINKID_DataType = "Number",
  210.             INPID_InputControl = "ComboControl",
  211.             INP_MinScale = 0,
  212.             INP_MaxAllowed = 3,
  213.             INP_MinAllowed = 0,
  214.             INP_MaxAllowed = 3,
  215.             INP_Integer = true,
  216.             ICD_Width = 1.0,
  217.             CC_LabelPosition = "Horizontal",
  218.             INP_DoNotifyChanged = true,
  219.             { CCS_AddString = "Vibrant", },
  220.             { CCS_AddString = "Simple", },
  221.             { CCS_AddString = "Complex", },
  222.             { CCS_AddString = "Power", },
  223.         })
  224.         InVibrance = self:AddInput("Vibrance", "Vibrance", {
  225.             LINKID_DataType = "Number",
  226.             INPID_InputControl = "SliderControl",
  227.             INP_Default = 0,
  228.             INP_MinScale = 0,
  229.             INP_MaxScale = 3,
  230.             INP_Default = 1,
  231.         })
  232.         InSaturation = self:AddInput("Saturation", "Saturation", {
  233.             LINKID_DataType = "Number",
  234.             INPID_InputControl = "SliderControl",
  235.             INP_MinScale = 0,
  236.             INP_MaxScale = 2,
  237.             INP_Default = 1,
  238.         })
  239.         InGain = self:AddInput("Gain", "Gain", {
  240.             LINKID_DataType = "Number",
  241.             INPID_InputControl = "SliderControl",
  242.             INP_MinScale = 0,
  243.             INP_MaxScale = 5,
  244.             INP_Default = 1,
  245.         })
  246.         InGamma = self:AddInput("Gamma", "Gamma", {
  247.             LINKID_DataType = "Number",
  248.             INPID_InputControl = "SliderControl",
  249.             INP_MinScale = 0,
  250.             INP_MaxScale = 2,
  251.             INP_Default = 1,
  252.         })
  253.     self:EndControlNest()
  254.    
  255.     self:BeginControlNest("Alpha", "Alpha", true, {})
  256.         InUnMultiply = self:AddInput("UnMultiply", "UnMultiply", {
  257.             LINKID_DataType = "Number",
  258.             INPID_InputControl = "CheckboxControl",
  259.             INP_Integer = true,
  260.             INP_Default = 0,
  261.         })
  262.         InAlphaGain = self:AddInput("Alpha Gain", "Alpha Gain", {
  263.             LINKID_DataType = "Number",
  264.             INPID_InputControl = "SliderControl",
  265.             INP_MinScale = 0,
  266.             INP_MaxScale = 1,
  267.             INP_Default = 0,
  268.         })
  269.     self:EndControlNest()
  270.    
  271.     self:BeginControlNest("Advanced", "Advanced", false, {})
  272.         InDepth = self:AddInput("Depth", "Depth", {
  273.             LINKID_DataType = "Number",
  274.             INPID_InputControl = "ComboControl",
  275.             INP_Default = 2.0,
  276.             INP_Integer = true,
  277.             ICD_Width = 1.0,
  278.             CC_LabelPosition = "Vertical",
  279.             INP_DoNotifyChanged = true,
  280.             { CCS_AddString = "int8", },
  281.             { CCS_AddString = "int16", },
  282.             { CCS_AddString = "float 16", },
  283.             { CCS_AddString = "float 32", },
  284.             INP_External = false,
  285.         })
  286.         InClip = self:AddInput("Clip Negative Pixels", "Clip Negative Pixels", {
  287.             LINKID_DataType = "Number",
  288.             INPID_InputControl = "CheckboxControl",
  289.             INP_Integer = true,
  290.             ICD_Width = 1.0,
  291.             INP_Default = 1,
  292.             INP_External = false,
  293.         })
  294.         DemoButton = self:AddInput("Demo", "Demo", {
  295.             LINKS_Name = "Demo",
  296.             LINKID_DataType = "Number",
  297.             INPID_InputControl = "ButtonControl",
  298.             BTNCS_Execute = OpenDemoURL,
  299.         })
  300.     self:EndControlNest()
  301.    
  302.     InImage = self:AddInput("Image", "Image", {
  303.         LINKID_DataType = "Image",
  304.         LINK_Main = 1,
  305.         INP_AcceptsGPUImages = true,
  306.     })
  307.     OutImage = self:AddOutput("Output", "Output", {
  308.         LINKID_DataType = "Image",
  309.         LINK_Main = 1,
  310.     })
  311. end
  312.  
  313.  
  314. function NotifyChanged(inp, param, time)
  315.     if inp ~= nil and param ~= nil then
  316.         if inp == InShowWheel then
  317.             if param.Value == 1.0 then
  318.                 InColorR:SetAttrs({ CLRC_ShowWheel = true, })
  319.             else
  320.                 InColorR:SetAttrs({ CLRC_ShowWheel = false, })
  321.             end
  322.         end
  323.     end
  324. end
  325.  
  326.  
  327. function Process(req)
  328.     local src = InImage:GetValue(req)
  329.     local depth = InDepth:GetValue(req).Value
  330.     local dst = Image{ IMG_Like = src, IMG_Depth = depth + 1, IMG_DeferAlloc = true }
  331.    
  332.     local node = DVIPComputeNode(req, "VibranceKernel", VibranceKernel, "VibranceParams", VibranceParams)
  333.     local params = node:GetParamBlock(VibranceParams)
  334.  
  335.     params.red = InColorR:GetValue(req).Value
  336.     params.green = InColorG:GetValue(req).Value
  337.     params.blue = InColorB:GetValue(req).Value
  338.     params.mode = InVibranceMode:GetValue(req).Value
  339.     params.vibrance = InVibrance:GetValue(req).Value
  340.     params.saturation = InSaturation:GetValue(req).Value
  341.     params.gain = InGain:GetValue(req).Value
  342.     params.gamma = InGamma:GetValue(req).Value
  343.     params.unmult = InUnMultiply:GetValue(req).Value
  344.     params.again = InAlphaGain:GetValue(req).Value
  345.     params.invert = InInvert:GetValue(req).Value
  346.     params.clip = InClip:GetValue(req).Value
  347.     params.srcCompOrder = src:IsMask() and 1 or 15
  348.  
  349.     node:SetParamBlock(params)
  350.  
  351.     node:AddInput("src", src)
  352.     node:AddOutput("dst", dst)
  353.  
  354.     local ok = node:RunSession(req)
  355.  
  356.     if not ok then
  357.         dst = nil
  358.     end
  359.        
  360.     OutImage:Set(req, dst)
  361. end

User avatar
SirEdric
Fusionator
Posts: 2263
Joined: Tue Aug 05, 2014 10:04 am
Answers: 9
Real name: Eric Westphal
Been thanked: 28 times
Contact:

Re: [RC] Vibrance Fuse

#170

Post by SirEdric » Fri Mar 27, 2020 12:02 am

Really cool stuff, mate!

User avatar
smirontsev
Posts: 6
Joined: Sat Mar 11, 2017 8:56 am
Real name: Sergey Mirontsev

Re: [RC] Vibrance Fuse

#171

Post by smirontsev » Fri Mar 27, 2020 12:43 am

Shem Namo wrote:
Thu Mar 26, 2020 12:34 pm
@intelligent machine ,
I'm still having trouble viewing the fuse.
I'm getting RT Kernel failed to build.

I'm just wondering are the // at line 105 and 115, supposed to be there?

It could be an issue with Notepad++, On my system it also changes the formatting when I paste it here on the forum.
Before posting any code here I use SciTe to fix the formatting issues.

Thanks again,
Same error. With download button too. :(

User avatar
SirEdric
Fusionator
Posts: 2263
Joined: Tue Aug 05, 2014 10:04 am
Answers: 9
Real name: Eric Westphal
Been thanked: 28 times
Contact:

Re: [RC] Vibrance Fuse

#172

Post by SirEdric » Fri Mar 27, 2020 12:49 am

Bugger....indeed!
This happens on Fu9 (probably expected)
...ata\Roaming\Blackmagic Design\Fusion\Fuses\Vibrance.fuse:333: attempt to call global 'DVIPComputeNode' (a nil value)
stack traceback:
...ata\Roaming\Blackmagic Design\Fusion\Fuses\Vibrance.fuse:333: in function <...ata\Roaming\Blackmagic Design\Fusion\Fuses\Vibrance.fuse:328>
Vibrance1 failed at time 0


And 16.2:
RT kernel VibranceKernel failed to build:
Vibrance1 failed at time 39
Last edited by SirEdric on Fri Mar 27, 2020 12:59 am, edited 1 time in total.

User avatar
Shem Namo
Fusionista
Posts: 349
Joined: Sun Oct 06, 2019 9:15 pm
Location: North Israel
Real name: David Kohen
Been thanked: 6 times

Re: [RC] Vibrance Fuse

#173

Post by Shem Namo » Fri Mar 27, 2020 12:53 am

@SirEdric , Do you happen to be trying to test the fuse with Fusion 9?

User avatar
SirEdric
Fusionator
Posts: 2263
Joined: Tue Aug 05, 2014 10:04 am
Answers: 9
Real name: Eric Westphal
Been thanked: 28 times
Contact:

Re: [RC] Vibrance Fuse

#174

Post by SirEdric » Fri Mar 27, 2020 12:59 am

Shem Namo wrote:
Fri Mar 27, 2020 12:53 am
Do you happen to be trying to test the fuse with Fusion 9?
I did indeed...:-)
(Just updated my above post)

User avatar
Shem Namo
Fusionista
Posts: 349
Joined: Sun Oct 06, 2019 9:15 pm
Location: North Israel
Real name: David Kohen
Been thanked: 6 times

Re: [RC] Vibrance Fuse

#175

Post by Shem Namo » Fri Mar 27, 2020 4:06 am

@SirEdric , I hate to be the one who has to tell you this
but, since this fuse uses DCTL for GPU acceleration, it doesn't work in Fusion 9. :oops:

Thanks

User avatar
intelligent machine
Fusionista
Posts: 509
Joined: Fri May 13, 2016 10:01 pm
Answers: 3
Location: Austin, Texas, USA
Real name: Sam Treadway
Been thanked: 13 times
Contact:

Re: [RC] Vibrance Fuse

#176

Post by intelligent machine » Fri Mar 27, 2020 4:36 am

We'll need to be sure and include that in the Description and maybe change the title of this topic to include (Fu16+)
I just downloaded the version from my post and it works just fine in Fu16 still.

User avatar
Shem Namo
Fusionista
Posts: 349
Joined: Sun Oct 06, 2019 9:15 pm
Location: North Israel
Real name: David Kohen
Been thanked: 6 times

Re: [RC] Vibrance Fuse

#177

Post by Shem Namo » Fri Mar 27, 2020 4:54 am

@intelligent machine , Good morning!
I added the minimum version to the original atom package.

I wrote 15+, because I'm pretty sure that it will also work in Resolve 15.

I'm afraid we might be looking at here is another compatibility issue .
Are you testing in Resolve or the standalone version?

Because I'm trying it out in Resolve 16.2 and am still getting an error.
I re-downloaded and restarted several times, but it didn't help.

We already had an issue with this fuse being compatible with Resolve but not Standalone.
Maybe you could try attaching a file instead of a code box?

Looking at the sample photos, I can say that this looks awesome.
You even used the original shockwave from the VC video!

The only change I would make to the control panel is, to make the INP Width of "Show Advanced", 0.75 instead of 0.5 (it clips the words a little)
I also see you changed the name of the "color" dropdown to Tint, now it matches the name :)

About the name, what do you think?
Should we leave it at Vibrance or Tintensity or do you have a better name in mind?

Thanks a million!!

User avatar
intelligent machine
Fusionista
Posts: 509
Joined: Fri May 13, 2016 10:01 pm
Answers: 3
Location: Austin, Texas, USA
Real name: Sam Treadway
Been thanked: 13 times
Contact:

Re: [RC] Vibrance Fuse

#178

Post by intelligent machine » Fri Mar 27, 2020 5:58 am

I works for me in Resolve also...just tested.
Vibrance.fuse
Let's gather full specs to track down the issue.
We need to make sure this is being tested in DR16.2 and Fu16.2.
OS?
Nvidia or AMD GPU?
You do not have the required permissions to view the files attached to this post.

User avatar
Shem Namo
Fusionista
Posts: 349
Joined: Sun Oct 06, 2019 9:15 pm
Location: North Israel
Real name: David Kohen
Been thanked: 6 times

Re: [RC] Vibrance Fuse

#179

Post by Shem Namo » Fri Mar 27, 2020 6:11 am

Okay, the download wasn't the problem.

My system specs are:

Windows 10,
Intel UHD 620 graphics card :D

It's definitely 16.2, I just upgraded 3 days ago.
Free version not Studio.

The thing is that: If I remove all of the vibrance math, the fuse works fine.
So I'm assuming that there's something going on over there.

I tried removing them one by one, but I couldn't pin-point it.

Thanks again,

User avatar
intelligent machine
Fusionista
Posts: 509
Joined: Fri May 13, 2016 10:01 pm
Answers: 3
Location: Austin, Texas, USA
Real name: Sam Treadway
Been thanked: 13 times
Contact:

Re: [RC] Vibrance Fuse

#180

Post by intelligent machine » Fri Mar 27, 2020 6:28 am

Shem Namo wrote:
Fri Mar 27, 2020 4:54 am
About the name, what do you think?
Should we leave it at Vibrance or Tintensity or do you have a better name in mind?
Personally, I prefer naming things like this on a high level according to what they do and what key words I would use in a search...so as I age and my memory goes to shit I'm not spending more time trying to remember what the name of that tool is that adds vibrance than actually using it. I don't like prepending initials or abbreviations either because - well, alphabetical sorting becomes an issue. That's just me.... For this one, I think either will be fine or use both as it kinda does both - adds tint and vibrance. "TIntensity Vibrance"?! I don't know.
Last edited by intelligent machine on Fri Mar 27, 2020 6:49 am, edited 1 time in total.