Jump to: Board index » General » Fusion

How to define custom variables in the Expression Modifier

Learn about 3D compositing, animation, broadcast design and VFX workflows.
  • Author
  • Message
Offline

Fernan

  • Posts: 5
  • Joined: Fri Oct 18, 2019 3:58 am
  • Real Name: Luis Fernando

How to define custom variables in the Expression Modifier

PostWed Jan 08, 2020 11:37 pm

Hi all.

I want to know if it is possible to make that. In After Effects you can define variables in expressions, and use them in any you want.

I guess this can be done in Fusion too, but I have not idea how to.

Basically I have a simple line like this one:

noise2(time/50, time/50)*1.5

But want to insert some variables in there (like I would do in After Effects):

var myTime = time/50;
var myFrec = 1.5
noise2(myTime, myTime)*myFrec

I know you can use the controls in the Modifier tab, but just want to know how to do it the other way :D

Thanks in advance.
Offline

Okke Verbart

  • Posts: 290
  • Joined: Tue Jan 17, 2017 8:40 pm

Re: How to define custom variables in the Expression Modifie

PostThu Jan 09, 2020 6:17 am

Hi Fernan - I was going to answer that you will need to proceed a multi-statement expression with a colon and that it ends with a semi-colon. Last statement would return the value with the return statement. So for instance:

Code: Select all
myTime = time/50;
myFrec = 1.5;
return noise2(myTime, myTime)*myFrec;


However, whilst these types of expressions are generally possible, they seem not to be possible when using the expression as a modifier, only as a direct simple expression. And to add to the complexity, the noise2 statement *is* possible in an expression modifier, but doesn't seem to be possible in a simple expression!

However, maybe Bryan (Ray) reads this and can chip in here!
www.ablackbirdcalledsue.com
Offline
User avatar

Bryan Ray

  • Posts: 2485
  • Joined: Mon Nov 28, 2016 5:32 am
  • Location: Los Angeles, CA, USA

Re: How to define custom variables in the Expression Modifie

PostThu Jan 09, 2020 3:13 pm

The Expression Modifier is a bit of a different beast than a simple expression field. The modifier's 'out' expressions can only receive input from its own fields—the Number In and Point In controls on the Controls tab. You can rename them on the Config tab, but you still have to use their original shortcut names in the expression itself: n1, n2, p1x, p2y, etc.

Let's suppose you put your myTime variable in Number In 1, and myFreq in Number In 2. In the Number Out field, you could use this expression:
noise2(n1, n1)*n2

The Modifier limits you to having only 27 such variables (9 scalars and 9 2d vectors). The Out fields are essentially just one big return statement—whatever is in there has to be a single formula, not a script.

Simple expressions using the colon prefix give you access to most of the Lua scripting language instead of the subset available in the modifier, and you can create User Controls to hold your variables if you need something interactive. Here's an example of a Dissolve node that uses that technique to randomly switch between its inputs:

Code: Select all
{
   Tools = ordered() {
      RandomSwitch_2 = Dissolve {
         Transitions = {
            [0] = "DFTDissolve"
         },
         CtrlWZoom = false,
         NameSet = true,
         Inputs = {
            Mix = Input {
               Value = 0,
               Expression = ":t0=0; randomseed(RandomSeed); while t0<=time do off=random(MinimumOffTime,MaximumOffTime); on=random(MinimumOnTime,MaximumOnTime); t=time-t0; t0=t0+on+off; end; n=t0-on; if t>off then return 1; else return 0; end",
            },
            Comments = Input { Value = "Randomly switches the Mix control between 0 and 1. Adjust the frequency of switching using the Max and Min sliders. \r\n\r\nMuse Effects Elements Library, Glitch Tools Collection\r\nby Bryan Ray.\r\nwww.musevfx.com", },
            MinimumOffTime = Input { Expression = "controlPanel_timeStutter.MinOffTime", },
            MaximumOffTime = Input { Expression = "controlPanel_timeStutter.MaxOffTime", },
            MinimumOnTime = Input { Expression = "controlPanel_timeStutter.MinShuffleDuration", },
            MaximumOnTime = Input { Expression = "controlPanel_timeStutter.MaxShuffleDuration", },
            RandomSeed = Input {
               Value = 67,
               Expression = "controlPanel_timeStutter.RandomSeed+250",
            },
         },
         ViewInfo = OperatorInfo { Pos = { 674, 31 } },
         UserControls = ordered() {
            MinimumOffTime = {
               INP_MaxAllowed = 10000,
               INP_Integer = true,
               INPID_InputControl = "SliderControl",
               IC_ControlPage = 0,
               INP_MaxScale = 30,
               INP_Default = 3,
               INP_MinAllowed = 0,
               LINKID_DataType = "Number",
               LINKS_Name = "Minimum Off Time",
            },
            MaximumOffTime = {
               INP_MaxAllowed = 10000,
               INP_Integer = true,
               INPID_InputControl = "SliderControl",
               IC_ControlPage = 0,
               INP_MaxScale = 60,
               INP_Default = 10,
               INP_MinScale = 1,
               INP_MinAllowed = 0,
               LINKID_DataType = "Number",
               LINKS_Name = "Maximum Off Time",
            },
            MinimumOnTime = {
               INP_MaxAllowed = 10000,
               INP_Integer = true,
               INPID_InputControl = "SliderControl",
               IC_ControlPage = 0,
               INP_MaxScale = 30,
               INP_Default = 3,
               INP_MinAllowed = 0,
               LINKID_DataType = "Number",
               LINKS_Name = "Minimum On Time",
            },
            MaximumOnTime = {
               INP_MaxAllowed = 10000,
               INP_Integer = true,
               INPID_InputControl = "SliderControl",
               IC_ControlPage = 0,
               INP_MaxScale = 60,
               INP_Default = 10,
               INP_MinScale = 1,
               INP_MinAllowed = 0,
               LINKID_DataType = "Number",
               LINKS_Name = "Maximum On Time",
            },
            RandomSeed = {
               LINKID_DataType = "Number",
               INP_Default = 0,
               IC_ControlPage = 0,
               INPID_InputControl = "SliderControl",
               LINKS_Name = "Random Seed",
            }
         }
      }
   },
   ActiveTool = "RandomSwitch_2"
}


If you expand the expression into discrete lines, it may look familiar. I cribbed the algorithm from Motionscript.com, and I've seen similar timeline segmentation expressions in AE frequently.

Code: Select all
:t0=0; randomseed(RandomSeed);
while t0<=time do
   off=random(MinimumOffTime,MaximumOffTime);
   on=random(MinimumOnTime,MaximumOnTime);
   t=time-t0;
   t0=t0+on+off;
end;
n=t0-on;
if t>off then
   return 1;
else
   return 0;
end
Bryan Ray
http://www.bryanray.name
http://www.sidefx.com
Offline

Okke Verbart

  • Posts: 290
  • Joined: Tue Jan 17, 2017 8:40 pm

Re: How to define custom variables in the Expression Modifie

PostThu Jan 09, 2020 7:51 pm

Some very good info Bryan :-) Still a shame to see such inconsistency in expression support (like the aforementioned noise2 function not being available in simple expressions for instance, or the fact that in some nodes the sin/cos/tan functions accept degrees as standard and in others radians; that tripped me up a few times!)

Oh, and btw, I just noticed that in my code example I had forgotten to precede it with a colon!
www.ablackbirdcalledsue.com
Offline

cristian_vogel

  • Posts: 3
  • Joined: Wed Oct 28, 2020 3:27 pm
  • Real Name: Cristian Vogel

Re: How to define custom variables in the Expression Modifie

PostSun Feb 21, 2021 5:38 pm

Hi.

I was interested to try this out, but I am confused about where I would paste this code in the Dissolve node? Would it be in the FrameRender scripts or other place?


[quote="Bryan Ray"]

Simple expressions using the colon prefix give you access to most of the Lua scripting language instead of the subset available in the modifier, and you can create User Controls to hold your variables if you need something interactive. Here's an example of a Dissolve node that uses that technique to randomly switch between its inputs:
Offline

cristian_vogel

  • Posts: 3
  • Joined: Wed Oct 28, 2020 3:27 pm
  • Real Name: Cristian Vogel

Re: How to define custom variables in the Expression Modifie

PostSun Feb 21, 2021 9:02 pm

OK, so I have been trying a basic idea which needs variables for a few hours now in DaVinci 17....

I just can't see how to do this.

My goal is to simply select a frame at random from a video, and hold it, whilst it is being composited. This requires two variables. One to increment and one to 'sample and hold' the randomly picked value.
I have tried...
Code: Select all
:   t = 0; tc=0;
   tc=tc+25;
   if ((tc % 5) == 0) then
      t=tc;
      return t;
   else
      return t;
   end


..in a simple expression of a TimeStretcher selecting the current frame.

but it seems the declaration
Code: Select all
 t=0; tc=0
resets the variable values every frame (?)

if I take them out, and move them to where I think they might belong ( the render start script) then it just never seems to initialise the variables. Any thoughts?
Offline

Okke Verbart

  • Posts: 290
  • Joined: Tue Jan 17, 2017 8:40 pm

Re: How to define custom variables in the Expression Modifie

PostTue Feb 23, 2021 4:26 pm

Yes, you are correct, it doesn't retain the values. For simple expressions, there's no such thing as variables that get retained over time (as in across more than one frame). Aside the pCustom in the particle system that is.

Despite this "limitation", a lot is still possible. I didn't quite get what you were exactly after. though Can you explain in more detail? Also, what confused me is that you use tc%5 when tc increases by 25 each time. This will always result in 0? (i.e. 25%5=0, 50%5 =0 etc)
www.ablackbirdcalledsue.com

Return to Fusion

Who is online

Users browsing this forum: No registered users and 21 guests