Page 1 of 1

Nuke's Soften filter equivalent?

PostPosted: Mon Apr 05, 2021 10:08 pm
by Philipp Walz
Hi there,

I want to unsharp my drone footage and tested various ways but found that Nuke's SOFTEN filter works best by default!
Is there any equivalent in Fusion? Blur is just not precise enough and I didn't figured out how to use the Multistep Blur effect from Reactor to work like Nuke's...

Here is a screenshot from the Nuke filter:
Bildschirmfoto 2021-04-06 um 00.06.30.png
Bildschirmfoto 2021-04-06 um 00.06.30.png (36.52 KiB) Viewed 804 times


Maybe somebody finds a way to recreate this in Fusion?

Re: Nuke's SOFTEN filter equivalent?

PostPosted: Tue Apr 06, 2021 12:14 am
by Bryan Ray
I'm not entirely sure I know what Nuke's Soften is doing, but I built an un-unsharp mask macro a while back. It's available through the Muse VFX website: http://www.musevfx.com/tools/

According to the Nuke docs, Soften "Uses Laplacian," which is aggravatingly vague. My guess is that it's doing something similar to my DeSharpen tool, except using a Laplacian filter, as described here: https://homepages.inf.ed.ac.uk/rbf/HIPR2/log.htm ;

You can make the convolutions the article illustrates using a CustomFilter node.

Re: Nuke's SOFTEN filter equivalent?

PostPosted: Tue Apr 06, 2021 10:18 am
by Philipp Walz
Thanks for your reply Bryan,

I know your DeSharpen tool (by the way, the link on your website is dead - I've found it via your blog). But the results look way to plastic for me. Sorry.
I just throwed the SOFTEN filter behinde the footage and it looks just right but I have absolutely no idea how to build this in Fusion :?: I have no experience in the Custom Filter to build a macro.
I followed your link and used the values described on the website but how do I move on from there? Use Channel Booleans to substract the data from the original? The results didn't look promising

Re: Nuke's SOFTEN filter equivalent?

PostPosted: Tue Apr 06, 2021 3:02 pm
by Steve Lodge
Is there anything in the DeFocus node that might do what you want? I've no experience with it to lend to you, but it gives different options to the Blur nodes and might be worth experimenting with.

Re: Nuke's SOFTEN filter equivalent?

PostPosted: Tue Apr 06, 2021 8:04 pm
by Bryan Ray
Thanks for letting me know about those broken links; I've passed the info along.

Steve, desharpening is a touch more complex than simply blurring. What happens in a sharpen operation is that the difference in luminance between neighboring pixels is exaggerated. Two pixels of nearly the same value will be unchanged, but if their luminance is extremely different, then the contrast between them is increased. To some extent, this process can be reversed by finding those same edges and subtracting the same sharpening filter instead of adding it. Sharpening can't be exactly reversed, though, because the original pixel values have been lost—all we can do is approximate them. As a result, the image will be slightly blurrier than the original, pre-sharpened image, but unpleasant crispiness and ringing can be reduced.

DeSharpen undoes an Unsharp Mask operation using this technique, mostly because Unsharp Mask is well documented and easy to perform. But it uses a Gaussian filter, which may create too broad an edge across with the smoothing happens. The Laplacian sharpener under consideration is evidently finer, capable of enhancing smaller details.

My guess is that you'd want to run your over-sharp footage into the CustomFilter using one of the given Laplacian kernels. This needs to be done in floating point, so you might need a ChangeDepth first. Then you'd subtract that result from the footage using ChannelBooleans (don't forget to set Alpha to Do Nothing). I believe the Gaussian control in Nuke would be a Blur applied before the CustomFilter.

One bit I'm unsure of is the Size control. "Adjusts the size of pixels within the channel defined by the channels control. Values less than 3 increase the light pixels and vice versa." I have no idea what that means.

Anyway, not having Nuke installed to test against, there's not much I can do to reverse engineer it at this time. You can give this a try and see if it gets close:

Code: Select all
{
   Tools = ordered() {
      CustomFilter1 = CustomFilter {
         CtrlWZoom = false,
         CustomData = {
            Settings = {
               [1] = {
                  Tools = ordered() {
                     CustomFilter1 = CustomFilter {
                        Inputs = {
                           Matrix = Input {
                              Value = FilterTable {
                                 Offset = 0,
                                 Type = 6,
                                 EndIn = 1,
                                 Maximum = 1,
                                 MaximumValue = 1,
                                 MinimumValue = 0,
                                 Minimum = 0,
                                 Table = { 0, 0, 9, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                                 NumEntries = 54,
                                 StartSlope = 1,
                                 StartIn = 0,
                                 EndSlope = 1
                              }
                           }
                        },
                        Name = "CustomFilter1",
                        CtrlWZoom = false,
                        ViewInfo = OperatorInfo { Pos = { 550, -82.5 } },
                        CustomData = {
                        }
                     }
                  }
               },
               [2] = {
                  Tools = ordered() {
                     CustomFilter1 = CustomFilter {
                        Inputs = {
                           Matrix = Input {
                              Value = FilterTable {
                                 Offset = 0,
                                 Type = 6,
                                 EndIn = 1,
                                 Maximum = 1,
                                 MaximumValue = 1,
                                 MinimumValue = 0,
                                 Table = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, -1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                                 EndSlope = 1,
                                 NumEntries = 54,
                                 StartIn = 0,
                                 StartSlope = 1,
                                 Minimum = 0
                              }
                           }
                        },
                        CtrlWZoom = false,
                        ViewInfo = OperatorInfo { Pos = { 660, -115.5 } },
                        CustomData = {
                        }
                     }
                  }
               },
            }
         },
         Inputs = {
            Blend = Input { Value = 0.58, },
            Matrix = Input {
               Value = FilterTable {
                  NumEntries = 54,
                  Type = 6,
                  Offset = 0,
                  Minimum = 0,
                  Maximum = 1,
                  MinimumValue = 0,
                  MaximumValue = 1,
                  StartSlope = 1,
                  EndSlope = 1,
                  StartIn = 0,
                  EndIn = 1,
                  Table = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 4, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
               },
            },
            Input = Input {
               SourceOp = "PipeRouter1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 275, 577.5 } },
      },
      ChannelBooleans4 = ChannelBoolean {
         Inputs = {
            Operation = Input { Value = 2, },
            Background = Input {
               SourceOp = "PipeRouter1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "CustomFilter1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 275, 610.5 } },
      },
      ChannelBooleans3_1 = ChannelBoolean {
         Inputs = {
            Blend = Input { Value = 0.973, },
            Operation = Input { Value = 2, },
            Background = Input {
               SourceOp = "PipeRouter1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "ChannelBooleans4",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 275, 643.5 } },
      },
      PipeRouter1 = PipeRouter {
         ViewInfo = PipeRouterInfo { Pos = { 165, 610.5 } },
      }
   }
}


Play with the center value in the CustomFilter, and the Blend in the second ChannelBooleans. I have no idea if it will be useful to you or not—it's just a few minutes of fiddling around.

Re: Nuke's Soften filter equivalent?

PostPosted: Wed Apr 07, 2021 9:16 am
by Steve Lodge
Great explanation Bryan, thank you

Re: Nuke's Soften filter equivalent?

PostPosted: Thu Apr 08, 2021 6:10 pm
by Philipp Walz
You mean something like this?
Bildschirmfoto 2021-04-08 um 20.09.07.png
Bildschirmfoto 2021-04-08 um 20.09.07.png (32.05 KiB) Viewed 537 times

Bildschirmfoto 2021-04-08 um 20.09.17.png
Bildschirmfoto 2021-04-08 um 20.09.17.png (75.34 KiB) Viewed 537 times

Bildschirmfoto 2021-04-08 um 20.09.24.png
Bildschirmfoto 2021-04-08 um 20.09.24.png (51.43 KiB) Viewed 537 times

Re: Nuke's Soften filter equivalent?

PostPosted: Thu Apr 08, 2021 8:06 pm
by Bryan Ray
Yeah, that's pretty close to what I was thinking. Does it remotely resemble what Nuke does?

Re: Nuke's Soften filter equivalent?

PostPosted: Fri Apr 09, 2021 7:39 am
by Philipp Walz
Bryan Ray wrote:Yeah, that's pretty close to what I was thinking. Does it remotely resemble what Nuke does?

It's definitely better than a simple blur node but not as good as Nuke's. It seems that Nuke's soften filter "attacks" the oversharpened edges better than Fusions method. Maybe it's in the settings...
But thanks a lot for helping me out :-D

Re: Nuke's Soften filter equivalent?

PostPosted: Fri Apr 09, 2021 3:58 pm
by Bryan Ray
Well again, I'll emphasize that this was a 5 minute doodle—I wouldn't expect it to be production-quality. But knowing that it's on the right track, perhaps somebody with the time and resources to be more rigorous can take it forward into an actual tool.

Re: Nuke's Soften filter equivalent?

PostPosted: Fri Apr 09, 2021 7:41 pm
by Philipp Walz
I just changed the value of the custom-filter to 4 instead of 3 and the result seems to get closer to Nuke.
Thank you Bryan for the lesson :-D

Re: Nuke's Soften filter equivalent?

PostPosted: Sat Apr 10, 2021 8:22 am
by Philipp Walz
Here's my approach which works quite well.

Code: Select all
{
   Tools = ordered() {
      ChangeDepth1_1 = ChangeDepth {
         CtrlWZoom = false,
         Inputs = {
            Depth = Input { Value = 4, },
         },
         ViewInfo = OperatorInfo { Pos = { 495, 280.5 } },
      },
      Blur1_1 = Blur {
         Inputs = {
            Filter = Input { Value = FuID { "Fast Gaussian" }, },
            XBlurSize = Input { Value = 0.3, },
            Input = Input {
               SourceOp = "ChangeDepth1_1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 605, 280.5 } },
      },
      CustomFilter1_1 = CustomFilter {
         Inputs = {
            Matrix = Input {
               Value = FilterTable {
                  NumEntries = 54,
                  Type = 6,
                  Offset = 0,
                  Minimum = 0,
                  Maximum = 1,
                  MinimumValue = 0,
                  MaximumValue = 1,
                  StartSlope = 1,
                  EndSlope = 1,
                  StartIn = 0,
                  EndIn = 1,
                  Table = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
               },
            },
            Input = Input {
               SourceOp = "Blur1_1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 715, 280.5 } },
      },
      ChannelBooleans1_1 = ChannelBoolean {
         Inputs = {
            Operation = Input { Value = 2, },
            ToAlpha = Input { Value = 4, },
            Background = Input {
               SourceOp = "Blur1_1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "CustomFilter1_1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 715, 313.5 } },
      },
      ChannelBooleans2_1 = ChannelBoolean {
         Inputs = {
            Blend = Input { Value = 0.5, },
            Operation = Input { Value = 2, },
            ToAlpha = Input { Value = 4, },
            Background = Input {
               SourceOp = "PipeRouter1_1",
               Source = "Output",
            },
            Foreground = Input {
               SourceOp = "ChannelBooleans1_1",
               Source = "Output",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 715, 346.5 } },
      },
      PipeRouter1_1 = PipeRouter {
         Inputs = {
            Input = Input {
               SourceOp = "ChangeDepth1_1",
               Source = "Output",
            },
         },
         ViewInfo = PipeRouterInfo { Pos = { 605, 346.5 } },
      }
   }
}

Re: Nuke's Soften filter equivalent?

PostPosted: Sun Apr 11, 2021 4:47 pm
by Bryan Ray
Glad you've got something working!