Welcome to WSL!

Make yourself at home, but before posting, please may I ask you to read the following topics.


Posting 101
Server space, screenshots, and you

Thank you!

PS. please pretty please:


Image

[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
Shem Namo
Fusionista
Posts: 502
Joined: Sun Oct 06, 2019 9:15 pm
Location: North Israel
Real name: David Kohen
Been thanked: 13 times

Re: [RC] Vibrance Fuse

#196

Post by Shem Namo » Sun Mar 29, 2020 1:39 pm

This might help,
There were a few places where a float value didn't have a f following it.

I'm not sure if it's much of a difference but it might be worth a try.
Do you guys want to test it?
It seems to work fine on my end.

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

User avatar
thibaud
Fusioneer
Posts: 193
Joined: Thu Sep 04, 2014 1:23 am
Been thanked: 6 times
Contact:

Re: [RC] Vibrance Fuse

#197

Post by thibaud » Sun Mar 29, 2020 2:35 pm

Shem Namo wrote:
Sun Mar 29, 2020 1:01 pm
@thibaud , Does the fuse return an image or does it just fail?
Thanks
with opencl, it does return an image. and switching the vibrance mode to any of the modes does work (the image is updated)
but as soon as I touch any of the intensity controls it fails
Warning: exception during GPU buffer download
ok it turns out it is manipulating the controls with the mouse that crash the fuse (something to do with the rates of updates I guess) , entering new value with the keyboard seems to work fine.

User avatar
thibaud
Fusioneer
Posts: 193
Joined: Thu Sep 04, 2014 1:23 am
Been thanked: 6 times
Contact:

Re: [RC] Vibrance Fuse

#198

Post by thibaud » Sun Mar 29, 2020 4:14 pm

I'd also suggest to use more appropriate default values, right now the image returned seems excessively overbright with the default 1.0 values.
I'd actually expect the default 1.0 value return the original image

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

Re: [RC] Vibrance Fuse

#199

Post by intelligent machine » Sun Mar 29, 2020 9:59 pm

After more review of the tool I found a need to process the source image before and after applying the colorization and vibrance features. While I'd usually do this with a BC or other appropriate tool, I wanted to experiment with this tool having a built-in BC in a "pre-" section.
You may have a source that is too bright or dim or may just want to completely desaturate it before adding the colorization. After adding in vibrance there may be a need to tweak these same values once again but only based on the result of the colorization/vibrance features.

So I've reworked the tool to include a "Pre-colorization" section which includes Gain, Gamma, Saturation, and Invert controls. (lift and brightness could easily be added)
The next section is "Colorize" followed by "Intensity" or "vibrance".
Within this intensity section you'll find the same saturation, gamma and gain controls but renamed to: "Post-Gain", "Post-Gamma", and "Post-Saturation" as they are applied to the resulting image after colorization and vibrance.

I did a pass and changed a few more numbers to floats.
I've also adjusted the positioning of a few controls and set the vibrance default to zero, instead of 1.

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

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

Re: [RC] Vibrance Fuse

#200

Post by Shem Namo » Sun Mar 29, 2020 11:33 pm

@intelligent machine, this looks cool, I've got to try this out.

One think i noticed is, at line 100 is there a way to make the sign float?
I tried fsign, but that doesn't seem to work.
I think that may be the compatibility issue.

This is a little different than what I originally had in mind.
This looks more like a round trip color grading tool.

One thing I thought to add to version 2, is something like Pop from Red Giant's "Colorista"
It's a really cool effect, but I couldn't find anything about it's algorithm online.
That's why I saved it for a future version.

I'll test this out and report some results

Thanks again,

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

Re: [RC] Vibrance Fuse

#201

Post by Shem Namo » Wed Apr 01, 2020 12:57 pm

I think it might be time to wrap this up.
Does anyone have any last minute errors that they would like to report?
I changed a couple last values to float.
I hope all of the issue are Resolved(No pun intended(okay, maybe a little bit.(more parentheses in this joke than in the fuse.)))

Thanks again guys,
Code: [Select all] [Expand/Collapse] [Download] (Vibrance.fuse)
  1. FuRegisterClass("Vibrance", CT_Tool, {
  2.     REGS_Category = "Fuses\\Color",
  3.     REGS_OpIconString = "VIB",
  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.     int mode;
  16.     float vibrance;
  17.     float csaturation;
  18.     float vsaturation;
  19.     float cgain;
  20.     float vgain;
  21.     float cgamma;
  22.     float vgamma;
  23.     int unmult;
  24.     int invert;
  25.     float again;
  26.     int clipblack;
  27.     int clipwhite;
  28.     int srcCompOrder;
  29. ]]
  30.  
  31. VibranceKernel = [[
  32.     __KERNEL__ void VibranceKernel(__CONSTANTREF__ VibranceParams *params, __TEXTURE2D__ src, __TEXTURE2D_WRITE__ dst) {
  33.         DEFINE_KERNEL_ITERATORS_XY(x, y);
  34.         float4 col = _tex2DVecN(src, x, y, params->srcCompOrder);
  35.         float luma = (col.x * 0.299f) + (col.y * 0.587f) + (col.z * 0.114f);
  36.         float vibrance = params->vibrance;
  37.  
  38.  
  39.         // Pre-Colorization Saturation:
  40.         col.x = params->csaturation * col.x + (1.0f - params->csaturation) * luma;
  41.         col.y = params->csaturation * col.y + (1.0f - params->csaturation) * luma;
  42.         col.z = params->csaturation * col.z + (1.0f - params->csaturation) * luma;
  43.  
  44.  
  45.         // Colorization Gain:
  46.         col.x *= params->cgain;
  47.         col.y *= params->cgain;
  48.         col.z *= params->cgain;
  49.  
  50.  
  51.         // Colorization Gamma:
  52.         col.x = powr(col.x, 1.0f / _fmaxf(params->cgamma, 0.01f));
  53.         col.y = powr(col.y, 1.0f / _fmaxf(params->cgamma, 0.01f));
  54.         col.z = powr(col.z, 1.0f / _fmaxf(params->cgamma, 0.01f));
  55.                        
  56.  
  57.  
  58.         // UnMultiply:
  59.         if (params->unmult == 1) {
  60.             col.w *= (luma + params->again);
  61.         }
  62.  
  63.  
  64.         // Invert Source:
  65.         if (params->invert == 1) {
  66.             col.x = col.w * (1.0f - col.x);
  67.             col.y = col.w * (1.0f - col.y);
  68.             col.z = col.w * (1.0f - col.z);
  69.         }
  70.  
  71.  
  72.         // Color Picker:
  73.         col.x += params->red * col.x;
  74.         col.y += params->green * col.y;
  75.         col.z += params->blue * col.z;
  76.        
  77.        
  78.         // Vibrance:
  79.         float cMax = _fmaxf(col.x, _fmaxf(col.y, col.z)); //strongest color
  80.         float cMin = _fminf(col.x, _fminf(col.y, col.z)); //weakest color
  81.         float cSat = cMax - cMin; //Saturation
  82.         float cAverage = (col.x + col.y + col.z) / 3.0f;
  83.         float scale = 1.0f;
  84.         float lerpWith = 0.0f;
  85.  
  86.             //Vibrant
  87.         if (params->mode == 0) {
  88.             scale = vibrance * (2.0f * (1.0f - cSat)); //Less Saturated given higher priority
  89.             if (cMax == col.x) { //special treatment when red is max
  90.                 scale = vibrance * (fabs(col.y - col.z) / (cSat / cAverage)) * (1.0f - cSat);
  91.             }
  92.             scale = _fminf(1.0f, scale); //clamp
  93.             lerpWith = cMax;
  94.         }
  95.             //Simple
  96.         if (params->mode == 1) {
  97.             scale = vibrance * ( 0.25f * (1.0f - cAverage));
  98.             lerpWith = cMin;
  99.         }
  100.             //Complex
  101.         if (params->mode == 2) {
  102.             scale = vibrance * (1.0f - (sign(vibrance) * cAverage));
  103.             lerpWith = cAverage;
  104.         }
  105.             //Power
  106.         if (params->mode == 3) {
  107.             scale = vibrance * (1.0f - powr(cSat, 1.0f / (vibrance + 1.0f)));
  108.             scale = _fminf(1.0f, scale); //clamp
  109.             lerpWith = cSat;
  110.         }
  111.             //lerp
  112.         col.x += scale * (col.x - lerpWith);
  113.         col.y += scale * (col.y - lerpWith);
  114.         col.z += scale * (col.z - lerpWith);
  115.  
  116.  
  117.         // Post-vibrance Gain:
  118.         col.x *= params->vgain;
  119.         col.y *= params->vgain;
  120.         col.z *= params->vgain;
  121.  
  122.  
  123.         // Post-vibrance Gamma:
  124.         col.x = powr(col.x, 1.0f / _fmaxf(params->vgamma, 0.01f));
  125.         col.y = powr(col.y, 1.0f / _fmaxf(params->vgamma, 0.01f));
  126.         col.z = powr(col.z, 1.0f / _fmaxf(params->vgamma, 0.01f));
  127.  
  128.  
  129.         // Post-Saturation:
  130.         col.x = params->vsaturation * col.x + (1.0f - params->vsaturation) * luma;
  131.         col.y = params->vsaturation * col.y + (1.0f - params->vsaturation) * luma;
  132.         col.z = params->vsaturation * col.z + (1.0f - params->vsaturation) * luma;
  133.                            
  134.  
  135.  
  136.         //Clip Black:
  137.         if (params->clipblack == 1) {
  138.             col.x = _fmaxf(col.x, 0.0f);
  139.             col.y = _fmaxf(col.y, 0.0f);
  140.             col.z = _fmaxf(col.z, 0.0f);
  141.         }
  142.                
  143.         //Clip White:
  144.         if (params->clipwhite == 1) {
  145.             col.x = _fminf(col.x, 1.0f);
  146.             col.y = _fminf(col.y, 1.0f);
  147.             col.z = _fminf(col.z, 1.0f);
  148.         }
  149.  
  150.         _tex2DVec4Write(dst, x, y, col);
  151.     }
  152. ]]
  153.  
  154. OpenDemoURL = [[
  155. -- Open a webpage window up using your default web browser
  156.     platform = (FuPLATFORM_WINDOWS and "Windows") or (FuPLATFORM_MAC and "Mac") or (FuPLATFORM_LINUX and "Linux")
  157.     function OpenURL(siteName, path)
  158.         if platform == "Windows" then
  159.             -- Running on Windows
  160.             command = "explorer \"" .. path .. "\""
  161.         elseif platform == "Mac" then
  162.             -- Running on Mac
  163.             command = "open \"" .. path .. "\" &"
  164.         elseif platform == "Linux" then
  165.             -- Running on Linux
  166.             command = "xdg-open \"" .. path .. "\" &"
  167.         else
  168.             print("[Error] There is an invalid Fusion platform detected")
  169.             return
  170.         end
  171.  
  172.         os.execute(command)
  173.         -- print("[Launch Command] ", command)
  174.         print("[Opening URL] [" .. siteName .. "] " .. path)
  175.     end
  176.  
  177.     OpenURL("Demo", "https://youtu.be/2XF8BsJ1J5o")
  178. ]]
  179.  
  180. function Create()
  181.     self:BeginControlNest("Pre-Colorization", "PreColorization", true, {})
  182.         InCGain = self:AddInput("Gain", "PreGain", {
  183.             LINKID_DataType     = "Number",
  184.             INPID_InputControl  = "SliderControl",
  185.             INP_MinScale        = 0,
  186.             INP_MaxScale        = 5,
  187.             ICD_Center          = 3,
  188.             INP_Default         = 1,
  189.         })
  190.         InCGamma = self:AddInput("Gamma", "PreGamma", {
  191.             LINKID_DataType     = "Number",
  192.             INPID_InputControl  = "SliderControl",
  193.             INP_MinScale        = 0,
  194.             INP_MaxScale        = 2,
  195.             INP_Default         = 1,
  196.         })
  197.         InCSaturation = self:AddInput("Saturation", "Saturation", {
  198.             LINKID_DataType     = "Number",
  199.             INPID_InputControl  = "SliderControl",
  200.             INP_MinScale        = 0,
  201.             INP_MaxScale        = 2,
  202.             INP_Default         = 1,
  203.         })             
  204.         InInvert = self:AddInput("Invert", "Invert", {
  205.             LINKID_DataType     = "Number",
  206.             INPID_InputControl  = "CheckboxControl",
  207.             INP_Integer         = true,
  208.             ICD_Width           = 1,
  209.             INP_Default         = 0,
  210.         })
  211.     self:EndControlNest()
  212.  
  213.     self:BeginControlNest("Colorize", "Colorize", true, {})
  214.         InShowWheel = self:AddInput("Show Advanced", "ShowAdvanced", {
  215.             LINKID_DataType     = "Number",
  216.             INPID_InputControl  = "CheckboxControl",
  217.             INP_Integer         = true,
  218.             ICD_Width           = 1.0,
  219.             INP_Default         = 0,
  220.             INP_External        = false,
  221.             INP_DoNotifyChanged = true,
  222.         })
  223.         InColorR = self:AddInput("Red", "Red", {
  224.             ICS_Name            = "Color",
  225.             LINKID_DataType     = "Number",
  226.             INPID_InputControl  = "ColorControl",
  227.             INP_Default         = 0,
  228.             INP_MaxScale        = 1.0,
  229.             ICD_Center          = 1.0,
  230.             INP_DoNotifyChanged = true,
  231.             CLRC_ShowWheel      = false,
  232.             IC_ControlGroup     = 1,
  233.             IC_ControlID        = 0,
  234.             IC_Visible          = true,
  235.         })
  236.         InColorG = self:AddInput("Green", "Green", {
  237.             LINKID_DataType     = "Number",
  238.             INPID_InputControl  = "ColorControl",
  239.             INP_Default         = 0,
  240.             INP_DoNotifyChanged = true,
  241.             IC_ControlGroup     = 1,
  242.             IC_ControlID        = 1,
  243.         })
  244.         InColorB = self:AddInput("Blue", "Blue", {
  245.             LINKID_DataType     = "Number",
  246.             INPID_InputControl  = "ColorControl",
  247.             INP_Default         = 0,
  248.             INP_DoNotifyChanged = true,
  249.             IC_ControlGroup     = 1,
  250.             IC_ControlID        = 2,
  251.         })
  252.     self:EndControlNest()
  253.  
  254.     self:BeginControlNest("Intensity", "Intensity", true, {})
  255.         InVibranceMode = self:AddInput("Vibrance Mode", "VibranceMode", {
  256.             LINKID_DataType     = "Number",
  257.             INPID_InputControl  = "ComboControl",
  258.             INP_MinScale        = 0,
  259.             INP_MaxScale        = 3,
  260.             INP_MinAllowed      = 0,
  261.             INP_MaxAllowed      = 3,
  262.             INP_Integer         = true,
  263.             ICD_Width           = 1.0,
  264.             CC_LabelPosition    = "Horizontal",
  265.             INP_DoNotifyChanged = true,
  266.             { CCS_AddString     = "Vibrant", },
  267.             { CCS_AddString     = "Basic", },
  268.             { CCS_AddString     = "Advanced", },
  269.             { CCS_AddString     = "Power", },
  270.         })
  271.         InVibrance = self:AddInput("Vibrance", "Vibrance", {
  272.             LINKID_DataType     = "Number",
  273.             INPID_InputControl  = "SliderControl",
  274.             INP_MinScale        = 0.0,
  275.             INP_MaxScale        = 5.0,
  276.             ICD_Center          = 2.0,
  277.             INP_Default         = 0,
  278.         })
  279.         InVSaturation = self:AddInput("Post-Saturation", "PostSaturation", {
  280.             LINKID_DataType     = "Number",
  281.             INPID_InputControl  = "SliderControl",
  282.             INP_MinScale        = 0,
  283.             INP_MaxScale        = 2,
  284.             INP_Default         = 1,
  285.         })
  286.         InVGain = self:AddInput("Post-Gain", "PostGain", {
  287.             LINKID_DataType     = "Number",
  288.             INPID_InputControl  = "SliderControl",
  289.             INP_MinScale        = 0,
  290.             INP_MaxScale        = 5,
  291.             ICD_Center          = 3,
  292.             INP_Default         = 1,
  293.         })
  294.         InVGamma = self:AddInput("Post-Gamma", "PostGamma", {
  295.             LINKID_DataType     = "Number",
  296.             INPID_InputControl  = "SliderControl",
  297.             INP_MinScale        = 0,
  298.             INP_MaxScale        = 2,
  299.             INP_Default         = 1,
  300.         })                 
  301.     self:EndControlNest()
  302.  
  303.     self:BeginControlNest("Alpha", "Alpha", false, {})
  304.         InUnMultiply = self:AddInput("UnMultiply", "UnMultiply", {
  305.             LINKID_DataType     = "Number",
  306.             INPID_InputControl  = "CheckboxControl",
  307.             INP_Integer         = true,
  308.             INP_Default         = 0,
  309.         })
  310.         InAlphaGain = self:AddInput("Alpha Gain", "Alpha Gain", {
  311.             LINKID_DataType     = "Number",
  312.             INPID_InputControl  = "SliderControl",
  313.             INP_MinScale        = 0,
  314.             INP_MaxScale        = 1,
  315.             INP_Default         = 0,
  316.         })
  317.     self:EndControlNest()
  318.  
  319.     self:BeginControlNest("Advanced", "Advanced", false, {})
  320.         InDepth = self:AddInput("Depth", "Depth", {
  321.             LINKID_DataType     = "Number",
  322.             INPID_InputControl  = "ComboControl",
  323.             INP_Default         = 2.0,
  324.             INP_Integer         = true,
  325.             ICD_Width           = 1.0,
  326.             INP_DoNotifyChanged = true,
  327.             { CCS_AddString     = "int8", },
  328.             { CCS_AddString     = "int16", },
  329.             { CCS_AddString     = "float 16", },
  330.             { CCS_AddString     = "float 32", },
  331.             INP_External        = false,
  332.         })
  333.         InClipBlack = self:AddInput("Clip Black", "Clip Black", {
  334.             LINKID_DataType     = "Number",
  335.             INPID_InputControl  = "CheckboxControl",
  336.             INP_Integer         = true,
  337.             ICD_Width           = 0.51,
  338.                         CC_LabelPosition = "Vertical",
  339.             INP_Default         = 1,
  340.             INP_External        = false,
  341.         })
  342.         InClipWhite = self:AddInput("Clip White", "Clip White", {
  343.             LINKID_DataType     = "Number",
  344.             INPID_InputControl  = "CheckboxControl",
  345.             INP_Integer         = true,
  346.             ICD_Width           = 0.54,
  347.                         CC_LabelPosition = "Vertical",
  348.             INP_Default         = 0,
  349.             INP_External        = false,
  350.         })             
  351.         DemoButton = self:AddInput("Demo", "Demo", {
  352.             LINKS_Name          = "Demo",
  353.             LINKID_DataType     = "Number",
  354.             INPID_InputControl  = "ButtonControl",
  355.             BTNCS_Execute       = OpenDemoURL,
  356.         })
  357.     self:EndControlNest()
  358.  
  359.     InImage = self:AddInput("Image", "Image", {
  360.         LINKID_DataType         = "Image",
  361.         LINK_Main               = 1,
  362.         INP_AcceptsGPUImages    = true,
  363.     })
  364.     OutImage = self:AddOutput("Output", "Output", {
  365.         LINKID_DataType         = "Image",
  366.         LINK_Main               = 1,
  367.     })
  368. end
  369.  
  370.  
  371. function NotifyChanged(inp, param, time)
  372.     if inp ~= nil and param ~= nil then
  373.         if inp == InShowWheel then
  374.             if param.Value == 1.0 then
  375.                 InColorR:SetAttrs({ CLRC_ShowWheel = true, })
  376.             else
  377.                 InColorR:SetAttrs({ CLRC_ShowWheel = false, })
  378.             end
  379.         end
  380.     end
  381. end
  382.  
  383.  
  384. function Process(req)
  385.     local src = InImage:GetValue(req)
  386.     local depth = InDepth:GetValue(req).Value
  387.     local dst = Image{ IMG_Like = src, IMG_Depth = depth + 1, IMG_DeferAlloc = true }
  388.     local node = DVIPComputeNode(req, "VibranceKernel", VibranceKernel, "VibranceParams", VibranceParams)
  389.     local params = node:GetParamBlock(VibranceParams)
  390.  
  391.     params.red = InColorR:GetValue(req).Value
  392.     params.green = InColorG:GetValue(req).Value
  393.     params.blue = InColorB:GetValue(req).Value
  394.     params.mode = InVibranceMode:GetValue(req).Value
  395.     params.vibrance = InVibrance:GetValue(req).Value
  396.     params.csaturation = InCSaturation:GetValue(req).Value
  397.     params.vsaturation = InVSaturation:GetValue(req).Value
  398.     params.cgain = InCGain:GetValue(req).Value
  399.     params.vgain = InVGain:GetValue(req).Value
  400.     params.cgamma = InCGamma:GetValue(req).Value
  401.     params.vgamma = InVGamma:GetValue(req).Value
  402.     params.unmult = InUnMultiply:GetValue(req).Value
  403.     params.again = InAlphaGain:GetValue(req).Value
  404.     params.invert = InInvert:GetValue(req).Value
  405.     params.clipblack = InClipBlack:GetValue(req).Value
  406.     params.clipwhite = InClipWhite:GetValue(req).Value 
  407.     params.srcCompOrder = src:IsMask() and 1 or 15
  408.  
  409.     node:SetParamBlock(params)
  410.  
  411.     node:AddInput("src", src)
  412.     node:AddOutput("dst", dst)
  413.  
  414.     local ok = node:RunSession(req)
  415.  
  416.     if not ok then
  417.         dst = nil
  418.     end
  419.  
  420.     OutImage:Set(req, dst)
  421. end

User avatar
thibaud
Fusioneer
Posts: 193
Joined: Thu Sep 04, 2014 1:23 am
Been thanked: 6 times
Contact:

Re: [RC] Vibrance Fuse

#202

Post by thibaud » Wed Apr 01, 2020 1:19 pm

The fact that it doesn't work on my (quite common - windows/nvidia) system:
1. You have to force opencl only.
2. touching any of the controls triggers a gpu error and requires a fusion restart.

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

Re: [RC] Vibrance Fuse

#203

Post by intelligent machine » Wed Apr 01, 2020 1:57 pm

I think the image (within the fuse's workspace) should be worked on in a temp image and then comped over black or transparent depending on whether unmultiply is checked before reaching the output.
Reason: (I mentioned this already) - check the histogram in the view with the tool active.

There are plenty of fuses that will adequately demo that workflow.

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

Re: [RC] Vibrance Fuse

#204

Post by Shem Namo » Wed Apr 01, 2020 11:26 pm

@thibaud , The last one didn't work either huh,
I though by changing the vibrance Mode from float to int would solve the issue.
@Midgardsormr , said earlier, that if you make an control that only has a few positions float,
that it might cause the compiler to do weird things. So I thought that doing that might change it.

@intelligent machine , Thanks for the tip!
Do you happen to know of a specific fuse that does this?

Thanks again,

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

Re: [RC] Vibrance Fuse

#205

Post by Shem Namo » Thu Apr 02, 2020 6:17 am

@thibaud If you have the time, could you please try out this latest version on your system?
I really want to fix the compatibility issue before tackling the histogram issue.

I saw some folks saying that they don't use the sign in OpenGL, because of some sort on compatibility issue.
So, I thought I'd replace the one in the fuse with a rather rudimentary one.

I think this has at least a chance of solving the issue.

Thanks for your patience,
Code: [Select all] [Expand/Collapse] [Download] (Vibrance.fuse)
  1. FuRegisterClass("Vibrance", CT_Tool, {
  2.     REGS_Category = "Fuses\\Color",
  3.     REGS_OpIconString = "VIB",
  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.     int mode;
  16.     float vibrance;
  17.     float csaturation;
  18.     float vsaturation;
  19.     float cgain;
  20.     float vgain;
  21.     float cgamma;
  22.     float vgamma;
  23.     int unmult;
  24.     int invert;
  25.     float again;
  26.     int clipblack;
  27.     int clipwhite;
  28.     int srcCompOrder;
  29. ]]
  30.  
  31. VibranceKernel = [[
  32.     __KERNEL__ void VibranceKernel(__CONSTANTREF__ VibranceParams *params, __TEXTURE2D__ src, __TEXTURE2D_WRITE__ dst) {
  33.         DEFINE_KERNEL_ITERATORS_XY(x, y);
  34.         float4 col = _tex2DVecN(src, x, y, params->srcCompOrder);
  35.         float luma = (col.x * 0.299f) + (col.y * 0.587f) + (col.z * 0.114f);
  36.         float vibrance = params->vibrance;
  37.  
  38.  
  39.         // Pre-Colorization Saturation:
  40.         col.x = params->csaturation * col.x + (1.0f - params->csaturation) * luma;
  41.         col.y = params->csaturation * col.y + (1.0f - params->csaturation) * luma;
  42.         col.z = params->csaturation * col.z + (1.0f - params->csaturation) * luma;
  43.  
  44.  
  45.         // Colorization Gain:
  46.         col.x *= params->cgain;
  47.         col.y *= params->cgain;
  48.         col.z *= params->cgain;
  49.  
  50.  
  51.         // Colorization Gamma:
  52.         col.x = powr(col.x, 1.0f / _fmaxf(params->cgamma, 0.01f));
  53.         col.y = powr(col.y, 1.0f / _fmaxf(params->cgamma, 0.01f));
  54.         col.z = powr(col.z, 1.0f / _fmaxf(params->cgamma, 0.01f));
  55.                        
  56.  
  57.  
  58.         // UnMultiply:
  59.         if (params->unmult == 1) {
  60.             col.w *= (luma + params->again);
  61.         }
  62.  
  63.  
  64.         // Invert Source:
  65.         if (params->invert == 1) {
  66.             col.x = col.w * (1.0f - col.x);
  67.             col.y = col.w * (1.0f - col.y);
  68.             col.z = col.w * (1.0f - col.z);
  69.         }
  70.  
  71.  
  72.         // Color Picker:
  73.         col.x += params->red * col.x;
  74.         col.y += params->green * col.y;
  75.         col.z += params->blue * col.z;
  76.        
  77.        
  78.         // Vibrance:
  79.         float cMax = _fmaxf(col.x, _fmaxf(col.y, col.z)); //strongest color
  80.         float cMin = _fminf(col.x, _fminf(col.y, col.z)); //weakest color
  81.         float cSat = cMax - cMin; //Saturation
  82.         float cAverage = (col.x + col.y + col.z) / 3.0f;
  83.         float scale = 1.0f;
  84.         float lerpWith = 0.0f;
  85.         float sVibrance = 0.0f;
  86.                
  87.         if (params->vibrance == 0) { sVibrance = 0.0f;
  88.         }
  89.         if (params->vibrance > 0) { sVibrance = 1.0f;
  90.         }
  91.         if (params->vibrance < 0) { sVibrance = -1.0f;
  92.         }
  93.  
  94.             //Vibrant                  
  95.         if (params->mode == 0) {
  96.             scale = vibrance * (2.0f * (1.0f - cSat)); //Less Saturated given higher priority
  97.             if (cMax == col.x) { //special treatment when red is max
  98.                 scale = vibrance * (fabs(col.y - col.z) / (cSat / cAverage)) * (1.0f - cSat);
  99.             }
  100.             scale = _fminf(1.0f, scale); //clamp
  101.             lerpWith = cMax;
  102.         }
  103.             //Simple
  104.         if (params->mode == 1) {
  105.             scale = vibrance * ( 0.25f * (1.0f - cAverage));
  106.             lerpWith = cMin;
  107.         }
  108.             //Complex
  109.         if (params->mode == 2) {
  110.             scale = vibrance * (1.0f - (sVibrance * cAverage));
  111.             lerpWith = cAverage;
  112.         }
  113.             //Power
  114.         if (params->mode == 3) {
  115.             scale = vibrance * (1.0f - powr(cSat, 1.0f / (vibrance + 1.0f)));
  116.             scale = _fminf(1.0f, scale); //clamp
  117.             lerpWith = cSat;
  118.         }
  119.             //lerp
  120.         col.x += scale * (col.x - lerpWith);
  121.         col.y += scale * (col.y - lerpWith);
  122.         col.z += scale * (col.z - lerpWith);
  123.  
  124.  
  125.         // Post-vibrance Gain:
  126.         col.x *= params->vgain;
  127.         col.y *= params->vgain;
  128.         col.z *= params->vgain;
  129.  
  130.  
  131.         // Post-vibrance Gamma:
  132.         col.x = powr(col.x, 1.0f / _fmaxf(params->vgamma, 0.01f));
  133.         col.y = powr(col.y, 1.0f / _fmaxf(params->vgamma, 0.01f));
  134.         col.z = powr(col.z, 1.0f / _fmaxf(params->vgamma, 0.01f));
  135.  
  136.  
  137.         // Post-Saturation:
  138.         col.x = params->vsaturation * col.x + (1.0f - params->vsaturation) * luma;
  139.         col.y = params->vsaturation * col.y + (1.0f - params->vsaturation) * luma;
  140.         col.z = params->vsaturation * col.z + (1.0f - params->vsaturation) * luma;
  141.                            
  142.  
  143.  
  144.         //Clip Black:
  145.         if (params->clipblack == 1) {
  146.             col.x = _fmaxf(col.x, 0.0f);
  147.             col.y = _fmaxf(col.y, 0.0f);
  148.             col.z = _fmaxf(col.z, 0.0f);
  149.         }
  150.                
  151.         //Clip White:
  152.         if (params->clipwhite == 1) {
  153.             col.x = _fminf(col.x, 1.0f);
  154.             col.y = _fminf(col.y, 1.0f);
  155.             col.z = _fminf(col.z, 1.0f);
  156.         }
  157.  
  158.         _tex2DVec4Write(dst, x, y, col);
  159.     }
  160. ]]
  161.  
  162. OpenDemoURL = [[
  163. -- Open a webpage window up using your default web browser
  164.     platform = (FuPLATFORM_WINDOWS and "Windows") or (FuPLATFORM_MAC and "Mac") or (FuPLATFORM_LINUX and "Linux")
  165.     function OpenURL(siteName, path)
  166.         if platform == "Windows" then
  167.             -- Running on Windows
  168.             command = "explorer \"" .. path .. "\""
  169.         elseif platform == "Mac" then
  170.             -- Running on Mac
  171.             command = "open \"" .. path .. "\" &"
  172.         elseif platform == "Linux" then
  173.             -- Running on Linux
  174.             command = "xdg-open \"" .. path .. "\" &"
  175.         else
  176.             print("[Error] There is an invalid Fusion platform detected")
  177.             return
  178.         end
  179.  
  180.         os.execute(command)
  181.         -- print("[Launch Command] ", command)
  182.         print("[Opening URL] [" .. siteName .. "] " .. path)
  183.     end
  184.  
  185.     OpenURL("Demo", "https://youtu.be/2XF8BsJ1J5o")
  186. ]]
  187.  
  188. function Create()
  189.     self:BeginControlNest("Pre-Colorization", "PreColorization", true, {})
  190.         InCGain = self:AddInput("Gain", "PreGain", {
  191.             LINKID_DataType     = "Number",
  192.             INPID_InputControl  = "SliderControl",
  193.             INP_MinScale        = 0,
  194.             INP_MaxScale        = 5,
  195.             ICD_Center          = 3,
  196.             INP_Default         = 1,
  197.         })
  198.         InCGamma = self:AddInput("Gamma", "PreGamma", {
  199.             LINKID_DataType     = "Number",
  200.             INPID_InputControl  = "SliderControl",
  201.             INP_MinScale        = 0,
  202.             INP_MaxScale        = 2,
  203.             INP_Default         = 1,
  204.         })
  205.         InCSaturation = self:AddInput("Saturation", "Saturation", {
  206.             LINKID_DataType     = "Number",
  207.             INPID_InputControl  = "SliderControl",
  208.             INP_MinScale        = 0,
  209.             INP_MaxScale        = 2,
  210.             INP_Default         = 1,
  211.         })             
  212.         InInvert = self:AddInput("Invert", "Invert", {
  213.             LINKID_DataType     = "Number",
  214.             INPID_InputControl  = "CheckboxControl",
  215.             INP_Integer         = true,
  216.             ICD_Width           = 1,
  217.             INP_Default         = 0,
  218.         })
  219.     self:EndControlNest()
  220.  
  221.     self:BeginControlNest("Colorize", "Colorize", true, {})
  222.         InShowWheel = self:AddInput("Show Advanced", "ShowAdvanced", {
  223.             LINKID_DataType     = "Number",
  224.             INPID_InputControl  = "CheckboxControl",
  225.             INP_Integer         = true,
  226.             ICD_Width           = 1.0,
  227.             INP_Default         = 0,
  228.             INP_External        = false,
  229.             INP_DoNotifyChanged = true,
  230.         })
  231.         InColorR = self:AddInput("Red", "Red", {
  232.             ICS_Name            = "Color",
  233.             LINKID_DataType     = "Number",
  234.             INPID_InputControl  = "ColorControl",
  235.             INP_Default         = 0,
  236.             INP_MaxScale        = 1.0,
  237.             ICD_Center          = 1.0,
  238.             INP_DoNotifyChanged = true,
  239.             CLRC_ShowWheel      = false,
  240.             IC_ControlGroup     = 1,
  241.             IC_ControlID        = 0,
  242.             IC_Visible          = true,
  243.         })
  244.         InColorG = self:AddInput("Green", "Green", {
  245.             LINKID_DataType     = "Number",
  246.             INPID_InputControl  = "ColorControl",
  247.             INP_Default         = 0,
  248.             INP_DoNotifyChanged = true,
  249.             IC_ControlGroup     = 1,
  250.             IC_ControlID        = 1,
  251.         })
  252.         InColorB = self:AddInput("Blue", "Blue", {
  253.             LINKID_DataType     = "Number",
  254.             INPID_InputControl  = "ColorControl",
  255.             INP_Default         = 0,
  256.             INP_DoNotifyChanged = true,
  257.             IC_ControlGroup     = 1,
  258.             IC_ControlID        = 2,
  259.         })
  260.     self:EndControlNest()
  261.  
  262.     self:BeginControlNest("Intensity", "Intensity", true, {})
  263.         InVibranceMode = self:AddInput("Vibrance Mode", "VibranceMode", {
  264.             LINKID_DataType     = "Number",
  265.             INPID_InputControl  = "ComboControl",
  266.             INP_MinScale        = 0,
  267.             INP_MaxScale        = 3,
  268.             INP_MinAllowed      = 0,
  269.             INP_MaxAllowed      = 3,
  270.             INP_Integer         = true,
  271.             ICD_Width           = 1.0,
  272.             CC_LabelPosition    = "Horizontal",
  273.             INP_DoNotifyChanged = true,
  274.             { CCS_AddString     = "Vibrant", },
  275.             { CCS_AddString     = "Basic", },
  276.             { CCS_AddString     = "Advanced", },
  277.             { CCS_AddString     = "Power", },
  278.         })
  279.         InVibrance = self:AddInput("Vibrance", "Vibrance", {
  280.             LINKID_DataType     = "Number",
  281.             INPID_InputControl  = "SliderControl",
  282.             INP_MinScale        = 0.0,
  283.             INP_MaxScale        = 5.0,
  284.             ICD_Center          = 2.0,
  285.             INP_Default         = 0,
  286.         })
  287.         InVSaturation = self:AddInput("Post-Saturation", "PostSaturation", {
  288.             LINKID_DataType     = "Number",
  289.             INPID_InputControl  = "SliderControl",
  290.             INP_MinScale        = 0,
  291.             INP_MaxScale        = 2,
  292.             INP_Default         = 1,
  293.         })
  294.         InVGain = self:AddInput("Post-Gain", "PostGain", {
  295.             LINKID_DataType     = "Number",
  296.             INPID_InputControl  = "SliderControl",
  297.             INP_MinScale        = 0,
  298.             INP_MaxScale        = 5,
  299.             ICD_Center          = 3,
  300.             INP_Default         = 1,
  301.         })
  302.         InVGamma = self:AddInput("Post-Gamma", "PostGamma", {
  303.             LINKID_DataType     = "Number",
  304.             INPID_InputControl  = "SliderControl",
  305.             INP_MinScale        = 0,
  306.             INP_MaxScale        = 2,
  307.             INP_Default         = 1,
  308.         })                 
  309.     self:EndControlNest()
  310.  
  311.     self:BeginControlNest("Alpha", "Alpha", false, {})
  312.         InUnMultiply = self:AddInput("UnMultiply", "UnMultiply", {
  313.             LINKID_DataType     = "Number",
  314.             INPID_InputControl  = "CheckboxControl",
  315.             INP_Integer         = true,
  316.             INP_Default         = 0,
  317.         })
  318.         InAlphaGain = self:AddInput("Alpha Gain", "Alpha Gain", {
  319.             LINKID_DataType     = "Number",
  320.             INPID_InputControl  = "SliderControl",
  321.             INP_MinScale        = 0,
  322.             INP_MaxScale        = 1,
  323.             INP_Default         = 0,
  324.         })
  325.     self:EndControlNest()
  326.  
  327.     self:BeginControlNest("Advanced", "Advanced", false, {})
  328.         InDepth = self:AddInput("Depth", "Depth", {
  329.             LINKID_DataType     = "Number",
  330.             INPID_InputControl  = "ComboControl",
  331.             INP_Default         = 2.0,
  332.             INP_Integer         = true,
  333.             ICD_Width           = 1.0,
  334.             INP_DoNotifyChanged = true,
  335.             { CCS_AddString     = "int8", },
  336.             { CCS_AddString     = "int16", },
  337.             { CCS_AddString     = "float 16", },
  338.             { CCS_AddString     = "float 32", },
  339.             INP_External        = false,
  340.         })
  341.         InClipBlack = self:AddInput("Clip Black", "Clip Black", {
  342.             LINKID_DataType     = "Number",
  343.             INPID_InputControl  = "CheckboxControl",
  344.             INP_Integer         = true,
  345.             ICD_Width           = 0.51,
  346.                         CC_LabelPosition = "Vertical",
  347.             INP_Default         = 1,
  348.             INP_External        = false,
  349.         })
  350.         InClipWhite = self:AddInput("Clip White", "Clip White", {
  351.             LINKID_DataType     = "Number",
  352.             INPID_InputControl  = "CheckboxControl",
  353.             INP_Integer         = true,
  354.             ICD_Width           = 0.54,
  355.                         CC_LabelPosition = "Vertical",
  356.             INP_Default         = 0,
  357.             INP_External        = false,
  358.         })             
  359.         DemoButton = self:AddInput("Demo", "Demo", {
  360.             LINKS_Name          = "Demo",
  361.             LINKID_DataType     = "Number",
  362.             INPID_InputControl  = "ButtonControl",
  363.             BTNCS_Execute       = OpenDemoURL,
  364.         })
  365.     self:EndControlNest()
  366.  
  367.     InImage = self:AddInput("Image", "Image", {
  368.         LINKID_DataType         = "Image",
  369.         LINK_Main               = 1,
  370.         INP_AcceptsGPUImages    = true,
  371.     })
  372.     OutImage = self:AddOutput("Output", "Output", {
  373.         LINKID_DataType         = "Image",
  374.         LINK_Main               = 1,
  375.     })
  376. end
  377.  
  378.  
  379. function NotifyChanged(inp, param, time)
  380.     if inp ~= nil and param ~= nil then
  381.         if inp == InShowWheel then
  382.             if param.Value == 1.0 then
  383.                 InColorR:SetAttrs({ CLRC_ShowWheel = true, })
  384.             else
  385.                 InColorR:SetAttrs({ CLRC_ShowWheel = false, })
  386.             end
  387.         end
  388.     end
  389. end
  390.  
  391.  
  392. function Process(req)
  393.     local src = InImage:GetValue(req)
  394.     local depth = InDepth:GetValue(req).Value
  395.     local dst = Image{ IMG_Like = src, IMG_Depth = depth + 1, IMG_DeferAlloc = true }
  396.     local node = DVIPComputeNode(req, "VibranceKernel", VibranceKernel, "VibranceParams", VibranceParams)
  397.     local params = node:GetParamBlock(VibranceParams)
  398.  
  399.     params.red = InColorR:GetValue(req).Value
  400.     params.green = InColorG:GetValue(req).Value
  401.     params.blue = InColorB:GetValue(req).Value
  402.     params.mode = InVibranceMode:GetValue(req).Value
  403.     params.vibrance = InVibrance:GetValue(req).Value
  404.     params.csaturation = InCSaturation:GetValue(req).Value
  405.     params.vsaturation = InVSaturation:GetValue(req).Value
  406.     params.cgain = InCGain:GetValue(req).Value
  407.     params.vgain = InVGain:GetValue(req).Value
  408.     params.cgamma = InCGamma:GetValue(req).Value
  409.     params.vgamma = InVGamma:GetValue(req).Value
  410.     params.unmult = InUnMultiply:GetValue(req).Value
  411.     params.again = InAlphaGain:GetValue(req).Value
  412.     params.invert = InInvert:GetValue(req).Value
  413.     params.clipblack = InClipBlack:GetValue(req).Value
  414.     params.clipwhite = InClipWhite:GetValue(req).Value 
  415.     params.srcCompOrder = src:IsMask() and 1 or 15
  416.  
  417.     node:SetParamBlock(params)
  418.  
  419.     node:AddInput("src", src)
  420.     node:AddOutput("dst", dst)
  421.  
  422.     local ok = node:RunSession(req)
  423.  
  424.     if not ok then
  425.         dst = nil
  426.     end
  427.  
  428.     OutImage:Set(req, dst)
  429. end

User avatar
thibaud
Fusioneer
Posts: 193
Joined: Thu Sep 04, 2014 1:23 am
Been thanked: 6 times
Contact:

Re: [RC] Vibrance Fuse

#206

Post by thibaud » Thu Apr 02, 2020 6:55 am

sorry, no change, touching any controls triggers a "Warning: exception during GPU buffer download"

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

Re: [RC] Vibrance Fuse

#207

Post by Shem Namo » Thu Apr 02, 2020 8:20 am

Thanks @thibaud ,
I'll keep trying

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

Re: [RC] Vibrance Fuse

#208

Post by Shem Namo » Thu Apr 02, 2020 12:07 pm

@Midgardsormr , I was just thinking,
Don't use a Windows machine with an Nvidia GPU?
If you do, does the latest version work on your end?

Thanks again,

User avatar
Midgardsormr
Fusionator
Posts: 1756
Joined: Wed Nov 26, 2014 8:04 pm
Answers: 14
Location: Los Angeles, CA, USA
Been thanked: 89 times
Contact:

Re: [RC] Vibrance Fuse

#209

Post by Midgardsormr » Thu Apr 02, 2020 2:29 pm

Nope. I get "RT kernel VibranceKernel failed to build:"

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

Re: [RC] Vibrance Fuse

#210

Post by intelligent machine » Thu Apr 02, 2020 7:02 pm

I 'think' I might know why this isn't working on Nvidia GPUs.
Let's see if this fixes it:

changed powr to _powf which I found after searching for just "DCTL" files on the webernets.
Vibrance.fuse
You do not have the required permissions to view the files attached to this post.