Bikeroom from Richard Greenwood on Vimeo.
Reel
Anty Saby
Tom Tom Snare
The English Rose
Dragon Ryder
Damon Hunter
Animate camera through Photoshop layers in Nuke
You can use camera-linked lens-in-focal, lens-in-aperture and z fields in a Card node in Nuke to easily line up and correctly scale layers from a 2D image. These fields are normally used to create a pan & tile dome.
Typically, this kind of motion graphic would be accomplished in Adobe After Effects, but after the switch to node based compositing, I find the layer based approach of AE less intuitive.
Here are the Steps
- Get 2D elements
- In this case I’m using artwork by Nigel Quarless
- Export layers as tiff with transparency (if you are using a simple 8bit Photoshop file, Nuke can handle the file directly).
- Drag into Nuke DAG
- Order them from left to right, front to back
- 3d Setup
- Add a camera
- The (horiz aperture / vert aperture) should equal your project settings’ full size format (w/h) ratio. I’m working in HD (1920/1080), my horiz aperture is 24, so my vert
aperture = 24 * (1080/1920) = 13.5. - You can leave the focal length at the default 50 for now
- The (horiz aperture / vert aperture) should equal your project settings’ full size format (w/h) ratio. I’m working in HD (1920/1080), my horiz aperture is 24, so my vert
- Add a Card node (Card1) to the first FG layer
- lens-in-focal = parent.Camera1.focal (ctrl drag the focal value from camera1)
- lens-in-aperture = parent.Camera1.haperture (tcrl drag the horiz aperture value from camera1)
- z = 1
- Duplicate Card1 for each additional layer
- z = (the previous Card’s z value) + .25
For example Card2.z = parent.Card1.z+.25 and Card3.z = parent.Card2+.25
- z = (the previous Card’s z value) + .25
- Connect everything to a Scene node
- Add a camera
- Animate Camera
- Duplicate Camera1 (Camera2)
- In the Viewer, lock to Camera2
- Adjust the focal value of Camera1 so that you can see all the 2d layers.
- in my case, I had to increase the focal value to 135.
- Animate the Camera2′s z value
- position playhead at the start of the animation
- set a key for z = -2.5 (this value will change based on how many layers you have)
- position playhead at the end of the animation
- set a key for z = 0
- Final steps
- Add some 3d motion blur if you want
- I wanted the last layer to fill the frame, so I added a transform geo node after the card (see the image below)
- reformat and write out.
You can see the project for which this was completed on vimeo. Or see my previous post.
Ladies Only 20th Anniversary
Ladies Only 20th Anniversary from Richard Greenwood on Vimeo.
Known all over as The Digger, Todd Fiander has been shaping mountain biking trails in North Vancouver for over 20 years.
On the 23rd June 2012, we celebrated the 20th Anniversary of one of his most innovative trails called “Ladies Only.”
I shot the video on a Canon 60D with an EFS 18-135mm and cut it together in Final Cut Pro to Jimi Hendrix’s Pali Gap.
In Nuke, I animated a camera move through the layers of the event poster, which was originally created by Nigel Quarless.
Just got my first post on nsmb.com!
Send to FFmpeg from Nuke Update
Ubuntu 12.04 has moved to avconv from ffmpeg and my previous python script to execute a shell script on Nuke’s afterRender callback needed to be updated appropriately.
Additional changes:
- The function now takes an arg ‘dnxhd’ to output a movie using the avid codec instead of the default x264.
- the renderSlug configuration option has been added
- when false: the movie start frame = the nuke project start frame*
- when true: the movie start frame = 0
* Note: You always have to render from frame 0 out of Nuke regardless of the project start frame (avconv image sequences always start at 0).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# Send rendered image sequence to shell avconv call def sendToAvconv(codec = 'x264'): # Configuration renderSlug = False vcodec = { 'x264' : 'libx264 -pre baseline', 'dnxhd' : 'dnxhd -b 36M', } extension = '.mov' # set some variables fps = nuke.root().knob('fps').value() firstFrame = nuke.root().knob('first_frame').value() ss = 0 if renderSlug == True else secondsToStr(firstFrame/fps) # grabs the write node's file value and makes sure the path uses printf style filenames imgSeqPath = nukescripts.replaceHashes(nuke.filename(nuke.thisNode())) # generate mov path base, ext = os.path.splitext(os.path.basename(imgSeqPath)) movPath = os.path.dirname(os.path.dirname(imgSeqPath)) + '/' + re.sub('\.?%0\d+d$', '', base) + extension # make shell command enc = 'avconv -y -r %s -i \'%s\' -an -ss %s -vcodec %s -threads 0 \'%s\'' % (fps, imgSeqPath, ss, vcodec[codec], movPath) subprocess.Popen(shlex.split(enc), stdout=subprocess.PIPE, stderr=subprocess.PIPE) # returns HH:MM:SS.SSS formatted string # http://code.activestate.com/recipes/511486/ def secondsToStr(t): rediv = lambda ll,b : list(divmod(ll[0],b)) + ll[1:] return "%02d:%02d:%02d.%03d" % tuple(reduce(rediv,[[t*1000,],1000,60,60])) |
Execute FFmpeg Command in Nuke AfterRender Callback
Update: there’s some new code to use avconv insead
Freelancing from home, I don’t have a dedicated render manager. Running Ubuntu 11.10, FFmpeg is the most convenient solution for rendering Quicktime movies for review.
With the help of NathanR and ivanbusquets over at the Nuke forums, I’ve got a working AfterRender callback that spawns a shell subprocess to automate the creation of .mov files from an image sequence rendered out of Nuke.
The Code
|
1 2 3 4 5 6 7 8 9 10 11 |
import os, re, shlex, subprocess def sendToFFmpeg(): # grabs the write node's file value and makes sure the path uses printf style filenames imgSeqPath = nukescripts.replaceHashes(nuke.filename(nuke.thisNode())) # generate mov path base, ext = os.path.splitext(os.path.basename(imgSeqPath)) movPath = os.path.dirname(os.path.dirname(imgSeqPath)) + '/' + re.sub('\.?%0\d+d$', '', base) + '.mov' # make shell command enc = 'ffmpeg -y -r 24 -i \'%s\' -an -vcodec libx264 -vpre slow -crf 22 -threads 0 \'%s\'' % (imgSeqPath, movPath) subprocess.Popen(shlex.split(enc), stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
Installation
- Add the above code to the ~/.nuke/menu.py.
- Add sendToFFmpeg() to the afterrender field in the python tab of your write node.
The .mov file should be created one directory up from rendered image sequence.
Note: FFmpeg assumes the image sequence starts at frame 0. At some point I’ll have to add an offset to adjust for those that don’t.


Sabrina has super strength and looks after anyone who needs a hand.
Tom plays drums by day. At night he hunts in the sub Alpine with a cross bow and his trusty dog.
Leigh prunes the undead while drinking Pimms.
A cyclist and dragon boater by day, Dave rides a dragon and wields a lightning infused oar. He wears a helmet for safety.
The first comic conversion.

