I’m back again with another custom tool for my Nuke setup. That can mean only one thing: I’m doing dumb stuff again.
I recently embarked on another large motion graphics project, animated entirely in Nuke. Just as with the creation of my Center Transform tool, using Nuke for such a project quickly reveals a glaring omission in the native Nuke toolset which, on this project, I just couldn't continue working without. I speak, of course, of Global Motion Blur Controls.
The Use Case
Most assets that move, especially motion graphics, need to have motion blur on them. But motion blur is incredibly processor-intensive, so, while you're working, it's almost always necessary to turn off motion blur while you animate, turning it back on to preview and render.
In Nuke, that means setting the motionblur parameter on a Transform node to 0 while you work, then setting it to 1 (or higher) to preview and render. Simple enough when you only have a handful of Transform nodes in your script. Nigh impossible to manage when you have almost 200.
Currently, each Transform node has its own set of motion blur controls: Samples, Shutter, and Shutter Offset. There is no mechanism for modifying or enabling / disabling all motion blur parameters at the same time like there is in, say, After Effects.
Smart Nuke artists will use Cloned Transform nodes or expression link the motion blur parameters to each other. Or, take it one step further and create a custom motion blur controller with a NoOp node and expression link all Transforms to that.
While that saves some effort, you've got to add the NoOp expression to every Transform node (twice), including each new Transform you create. And, of course, there's the very likely possibility that you'll forget or miss one along the way and have to track it down once you notice your render looks wrong.
This is how I have previously dealt with this problem.
A Half-Step Forward
To make this process faster, I wrote a script to quickly expression link the motionblur and shutter parameters of selected nodes to my custom NoOp, which I have saved as a Toolset for easy access in each new Nuke script.
That script looks like this:
def SetNoOpBlur(): for xNode in nuke.selectedNodes(): xNode['motionblur'].setExpression( 'NoOp1.mBlur' ) xNode['shutter'].setExpression( 'NoOp1.mShutter' ) toolbar = nuke.menu("Nodes") gzmos = toolbar.addMenu("Gizmos", icon='Gizmos4.png') gzmos.addCommand("Link NoOp Blur Control", 'SetNoOpBlur()')
This makes the expression linking faster and easier, but I still have to select all the Transform nodes by hand before running the script. It's also incredibly fragile since I hard-coded the name of the controller node (NoOp1) into the function.
This level of half-assed automation simply won't do. We need to whole-ass a better solution.
The goal would be to have motion blur settings in the Nuke script's Project Settings that control all Transform nodes by default, with the ability to override each node's individual settings, as needed.
Here’s what I came up with :
# Customize Transform Controls - No Center Transform Button def OnTransformCreate(): nTR = nuke.thisNode() if nTR != None: # Create "Use Local Motion Blur" button lbscript="mbT = nuke.thisNode()['motionblur']; mbT.clearAnimated(); stT = nuke.thisNode()['shutter']; stT.clearAnimated(); soT = nuke.thisNode()['shutteroffset']; stT.clearAnimated();" lb = nuke.PyScript_Knob('clear-global-mblur', 'Use Local Motion Blur') lb.setCommand(lbscript) nTR.addKnob(lb) # Create "Use Global Motion Blur" button gbscript="nBB = nuke.thisNode(); nBB['motionblur'].setExpression('root.motionblur'); nBB['shutter'].setExpression('root.shutter'); nBB['shutteroffset'].setExpression('root.shutteroffset');" gb = nuke.PyScript_Knob('use-global-mblur', 'Use Global Motion Blur') gb.setCommand(gbscript) nTR.addKnob(gb) # Set Transform Node to use Global Motion Blur by Default nTR['motionblur'].setExpression('root.motionblur') nTR['shutter'].setExpression('root.shutter') nTR['shutteroffset'].setExpression('root.shutteroffset') nuke.addOnUserCreate(OnTransformCreate, nodeClass="Transform") # Root Modifications for Global Motion Blur def GlobalMotionBlur(): ## Create Motion Blur tab in Project Settings nRT = nuke.root() tBE = nuke.Tab_Knob("Motion Blur") nuke.Root().addKnob(tBE) ## Create motionblur, shutter, and shutter offset controls, ranges, and defaults mBL = nuke.Double_Knob('motionblur', 'motionblur') mBL.setRange(0,4) sTR = nuke.Double_Knob('shutter', 'shutter') sTR.setRange(0,2) oFS = nuke.Enumeration_Knob('shutteroffset', 'shutter offset', ['centered', 'start', 'end']) oFS.setValue('start') ## Add new knobs to the Motion Blur tab mblb = nuke.Text_Knob("gmbcl","Global Motion Blur Controls") nRT.addKnob(mblb) nRT.addKnob(mBL) nRT.addKnob(sTR) nRT.addKnob(oFS) GlobalMotionBlur()
# Global Motion Blur Defaults nuke.knobDefault("Root.motionblur", "1") nuke.knobDefault("Root.shutter", ".5") nuke.knobDefault("Root.shutteroffset", "start")
I’ve created global parameters for Motion Blur, Shutter, and Shutter Offset . When you create a Transform node, it automatically adds 2 buttons to the User tab to make it easy to unlink / re-link to the global controller.
In my version, all Transform nodes created are linked to the global setting by default. If you'd prefer each node be un-linked by default, you can just remove the last 3 lines of the OnTransformCreate() function. Then, you can click the "Use Global Motion Blur" button on each node that you want to link.
While I haven't spent a ton of time with this new setup, I'm really happy with how it's come out. Though, as with most of my weird customizations, I look forward to the day that The Foundry adds this functionality to the app, making my code obsolete.
I did not add the Custom Shutter Offset control to the global controller because, for one, I really don’t use that option much (or ever), and two, it turned out to be much harder to script than the rest of the options. It simply wasn’t worth the effort to figure out how to create a global controller for something I never use, and the command is still accessible by using per-node motion blur settings. ↩