As I continue to use Nuke in ways in which it was never intended to be used (read: motion graphics), I keep finding small bits of friction that I just can't help but remove with app customizations.
My latest annoyance stems from an animated project that involved more traditional motion-graphics-style animation than the typical interface design and animation I usually create. I built all the graphic assets I would need for the video ahead of time, then assembled and animated them into a sequence, entirely in Nuke.
Again and again, I would merge a new graphic asset onto my shot, and I would have to do some math to figure out how to transform it into the center of the frame. Since the origin (0,0) of a Nuke frame is the bottom left corner, by default, images show up in the lower left of the frame rather than the center. Which is not what I want.
So, I'd add a Transform to the asset and move it to the center of the 1920 x 1080 frame. Since I care about precision, I didn't just eyeball the transform. I want it to be exact.
As long as I add a Transform to a graphic element with the upstream node selected, the Transform will detect the width and height of the asset and place the transform jack in the center of the object. As a Nuke user, you already knew that.
Then, I place my cursor in the
x translate parameter box and type
1920/2 - whatever value was in the
x center position, as determined by the upstream node. I repeat this process for the
y translate parameter, using
1080/2 to match the frame's height.
And lo, we have discovered another simple, math-based operation, prone to human error, ripe for automation. The formula is simple:
x translateparameter should be defined as half the
frame widthminus half the
y translateparameter should be defined as half the
frame heightminus half the
- If we have added the Translate node directly to the asset — which is to say we have not added it to our script unconnected — the
y centerparameters will be automatically filled with the half-width and half-height values of our asset.
In Nuke Python, this formula would be expressed as:
n = nuke.thisNode() # Get the x and y values of the Transform's center point xVal = n['center'].value(0) yVal = n['center'].value(1) # Get the width and height of the frame format rVal = nuke.Root() xfVal = rVal.width() yfVal = rVal.height() # Define the variables to set the translate values txVal = n['translate'].value(0) tyVal = n['translate'].value(1) # Find difference between center of frame and center of transform cxVal = xfVal/2-xVal cyVal = yfVal/2-yVal # Translate to center of frame format n['translate'].setValue(cxVal, 0) n['translate'].setValue(cyVal, 1)
Next, we take that nicely formatted Python script and shove it into an
addOnUserCreate function within our Menu.py file thusly:
def OnTransformCreate(): nTR = nuke.thisNode() if nTR != None: script="n = nuke.thisNode(); xVal = n['center'].value(0); yVal = n['center'].value(1); rVal = nuke.Root(); xfVal = rVal.width(); yfVal = rVal.height(); txVal = n['translate'].value(0); tyVal = n['translate'].value(1); cxVal = xfVal/2-xVal; cyVal = yfVal/2-yVal; n['translate'].setValue(cxVal, 0); n['translate'].setValue(cyVal, 1);" k = nuke.PyScript_Knob('center_trans', 'Center Transform') k.setCommand(script) nTR.addKnob(k) nuke.addOnUserCreate(OnTransformCreate, nodeClass="Transform")
Now, every Transform node created will have a nice big "Center Transform" button added to it automatically.
So, when I bring in a 584 x 1024 graphic asset like, say, this:
And I merge it over a 1920 x 1080 background...
...add a Transform node — which will find the center point to be (292,512)
All I have to do to center my graphic asset is click this button...
...and boom. Automated.