## Using waves to drive animation in Nuke – part 2

In my previous article on this subject I gave some examples of expressions that you can just copy and paste into any value in Nuke to quickly create an infinitely repeating animating pattern. I was asked in the comments how to do a ‘blink expression every x frames’. I answered with ‘just use the square wave example’, but I realised that’s not what he was after. In this article I’ll give you some expressions that can be used for such a blink or ‘blip’ animation curve.

I have also made a new version of my gizmo WaveMaker that incorporates all of this, so you can download that if you’d prefer. It’s now in .nk format rather than .gizmo so it’s easier to share.

### Square on/off blip every n frames

(((((sin(((frame*(pi*2/(freq/2))/2)+offset))+1)/2)) > cutoff ? 1 : 0) * (maxVal-minVal) ) + minVal

(Where ‘freq’ is the number of frames between blips, ‘offset’ is the time offset, ‘cutoff’ is a value between 0 and 1 which controls the width of each blip, ‘minVal’ is the lower value, ‘maxVal’ is the upper value. As in the previous article, either replace these variable names with your values, or better still, create a NoOp node, add some user knobs with those names and you’ll be able to adjust it on the fly)

Simpler version: ((( sin( ( ( frame * ( pi * 2 / ( 5 / 2 ) ) / 2 ) + 0.5 ) ) + 1 ) / 2 ) ) > 0.95 ? 1 : 0

(Blip pattern between 0 and 1, replace the ‘5’ to adjust amount of frames between blips, adjust the ‘0.5’ to move the whole thing back and forth in time, and adjust the ‘0.95’ to adjust the width of the blips)

### So what’s it doing?

It’s really just a simple sine wave with another expression applied to see when that sine wave goes above the cutoff point. If so, set the value to 1, if not, set it to zero. If a high enough cutoff point is given (like 0.95) most of the time the sine wave will be below that value and only at the very tip of the peak go above it. The lower the cutoff, the longer the peak rises above the cutoff point and so the blip gets wider.

But if you need something a bit smoother than a simple on/off, I’ve also made this version:

### Smooth pulse-like blip every n frames

(min((max((((((sin(((frame*(pi*2/(freq/2))/2)+offset))+1)/2)) > cutoff ? (((sin(((frame*(pi*2/(freq/2))/2)+offset))+1)/2)) : 0)) – cutoff,0) * (1/(1-cutoff)) * 1.001),1) * (maxVal-minVal) ) + minVal

Slightly simpler version: (min( (max( ((((( sin( (( frame*( pi * 2 / ( 10 / 2 ) ) / 2 ) + 1.55 )) + 1 ) / 2 )) > 0.7 ? (((sin( ( (frame * ( pi * 2 / ( 10 / 2 ) ) / 2 ) + 1.55 ) ) + 1 ) / 2 )) : 0 )) – 0.7 , 0 ) * ( 1 / ( 1 – 0.7 )) * 1.001) , 1 ))

(Smooth blip pattern between 0 and 1, replace the ’10’s to adjust amount of frames between blips, adjust the ‘1.55’s to move the whole thing back and forth in time, and adjust the ‘0.7’s to adjust the width of the blips)

### Multiple blips

To make a complex repeating pattern of blips, create several user knobs using the above expressions, set to different values, then in another user knob max them all together:

max( max( blip1, blip2 ) , blip3 )

### Manual looping

Remember, if you just need a quick repeating pattern for one thing in one shot, then building all these expressions is probably overkill because you can just draw a pattern in the curve editor, then tell Nuke to loop that pattern. This is more for the cases where you may have several things blinking on and off at different rates (perhaps a HUD, graphics display or warning lights on buildings), and you may need to go and adjust them all later. I personally wouldn’t go to the trouble of building all the knobs each time, that’s why I built BlipMaker into my WaveMaker gizmo so it’s available whenever I need it. My article where I took all my expressions from WaveMaker and made them available for quick copying and pasting has proved rather popular though so I thought I’d do the same for BlipMaker.

# WaveMaker v4 available

Edit on 12/10/2013: This tool has been superceded by my new tool Animation Maker.

If you are familiar with my gizmo WaveMaker, I have made another version with two differences:

1) BlipMaker added. Allows you to generate blip animations for animating flashing beacons, LED lights or anything that needs to blip on for a frame or so every few seconds. WaveMaker itself can’t generate such a curve, it can only create squared versions of existing waves, meaning you could get it to come on for a frame, but it would only be off for another frame before it came on again. BlipMaker lets you choose the ‘on’ length and ‘off’ length separately. Examples below.

2) Instead of sharing the gizmo, I have provided a .nk file with a group node inside. If you want to use it as a gizmo, just load up the file, load the group in the properties tab, and Export as Gizmo… from the Node tab. However if you want to avoid problems when sharing your scripts, you can just import this .nk file into your script whenever you need it. The third, best option is to use the provided example menu.py file to create a custom button in your toolbar that looks and behaves like a regualar gizmo but is in fact just importing that .nk file each time you press it.

## BlipMaker

Example curve: Blip of one frame, every 24 frames

Example curve: Soft blip over three frames, every 24 frames

Example curve: Three one frame blips, every 24 frames

Example curve: Combination pattern of blips with different settings, every 24 frames

These are just a few examples, you can play around with the sliders to get all sorts of combinations. Feel free to drop me a line or leave a comment if you use WaveMaker in any of your projects, I’m always interested to see how people use it.

If you just need to grab these expressions quickly, have a look this article where I break it down further.

## Nuke: Retiming tracking data and cameras

### Retiming a curve

There are many retiming options in Nuke but how do you retime tracking data or animation?
The answer is actually very simple and can be used wherever you have an animation curve in your script. If you are using an OFlow node, called ‘OFlow1’, and are using ‘Source Frame’ timing, rather than ‘Speed’ to retime a plate, you can access the retime curve by referring to ‘OFlow1.timingFrame‘.

So if you apply the following expression to any other curve in your script, that animation curve will be retimed to match OFlow1:
curve(OFlow1.timingFrame)

Translated: “For the frame I am currently on, instead of using the current value, jump to the frame the OFlow is currently looking at and use the value from this curve at that frame“.

# Offsetting a curve

Any control that has keyframe animation, right click the curve icon and choose ‘Edit Expressions…‘ and you should see it has one expression in there already: ‘curve‘. This is just the curve created from your keyframes. You can treat that curve like a variable, for example ‘curve*2‘ to double the amplitude of the curve. Putting a value in brackets after it allows you to slip the curve back and forth in time. ‘curve(frame-5)‘ would offset the curve by 5 frames. “At this frame, don’t use this value, use the one 5 frames earlier“. ‘frame‘ is a variable that always contains the current frame number. The resulting output would look something like this:

# An example script

Let’s say you have a shot of a building and you want to patch in some extra windows. You don’t want to use a still because there are shadows of people moving around inside the building so you want to copy another window, translate it to the new position and then retime the input so the people moving round look less repetitive. If it was a locked off shot, you could just retime it, copy and translate it. But if there is a camera move and camera wobble it will need to be stabilized, translated then match-moved. But where do you put the retime node? It makes sense to put it after the stabilize, but then you will break concatentation with the translate and match-move nodes, potentially introducing softening. Using the above method of retiming the tracking data, you can keep the transform nodes together and keep concatentation.

In this example I’m using a CornerPin node as my stablize/match-move, exported from Mocha Pro.

One of the patches in this example doesn’t use any retiming, and the other does. They use an identical setup but one has expressions linked to the OFlow. I have put a dot node in there so you can see the expression line more clearly. The CornerPin nodes labelled ‘stabilize’ and ‘match’ are identical but the stabilize ones have the ‘invert’ check box ticked. I could have cloned several of them but the tracking data is unlikely to change so a straight copy/paste is better here.

When I right click on any parameter in cornerPinTrack4 and choose ‘Edit Expressions…‘ I enter the above expression into each corner:

No matter how I animate my OFlow1 node, the cornerPinTrack4 node will adjust it’s tracking data to match the newly retimed plate, keeping it stabilized. Of course, if you retime it to extremes, the plate and/or tracking data will run out. In this example I have just slowed it down and sped it up again. The retime curve looks like this:

When I look at the curve for one of the values in my corner pin (the x value of corner 1) it shows the original keyframes with the newly calculated curve on top:

I drew the roto shape on my reference frame around the window I wanted to copy, whilst looking at the result of the cornerPinTrack4. I then cloned the offset transform node and put it beneath the roto shape. I could have just viewed the result of the offset transform node when I drew my rotoshape to achieve the same thing, but this way I can change my mind about the offset later if I want, moving it to a different position and the rotoshape will always be in the correct place.

To avoid grain issues you will probably want to degrain the plate and regrain the patches afterwards. Even if it doesn’t get softened, you don’t want grain running at different speeds.

# Using a TimeWarp node instead

If you are retiming with a timewarp node, you can use the ‘lookup’ value instead to achieve the same thing:
curve(TimeWarp1.lookup)

# Summary

This trick can be used anywhere in your nuke script; anywhere there’s a keyframed knob, you can adjust the curve by adding an expression to it. In most cases retiming is done to the plate beforehand or at the end of a comp, so your matchmove will have been done on the retimed plate already, or if at the end, then it doesn’t matter. But occasionally a decision will be made later on, after you have your matchmove, to retime something and it means throwing off all your animation. But using this expression you can keep the existing animation, whether that be tracking, a 3D camera, switches, fades or transforms, and avoid precomps and other methods that might introduce softness by breaking concatenation.

And yes, I did say 3D camera… if you have a tracked camera but the plate has to be retimed, you can put this expression on every animated value in that camera (once you untick ‘read from file‘) and the camera will now match the retimed plate. No need to send it back to the matchmove department.

## Nuke: Creating paintings

### My new Nuke tool: RandomTile.

Tile a given image at random positions, sizes and rotations, filling the project format.

This new tool of mine was more of a test to see how far I can push Nuke. When it didn’t explode and take the computer with it, I added more and more features and to my surprise Nuke took it on the chin. It turns out that there’s seemingly no limit to the amount of nodes in a script, so long as you put them in a group.

RandomTile can be used in many ways including:

1) Splatter a shape or image randomly over the screen at varying sizes and rotations. Useful if you want to quickly create a larger texture or repeating pattern to wrap onto some geometry, for example. This is why I initially made the tool; the existing Tile node just repeats the image in a uniform grid. Even using several Tile nodes and rotating them and moving them around on top of each other still produces obvious repeating lines. Here’s an example plugging the standard ColorWheel into RandomTile:

2) Make simple 2D particles by plugging in an animated shape. It will randomly offset the time for each tile. Take the above ColorWheel and put a transform after it, animating it back and forth, up and down, doesn’t matter if it goes way off screen, then make a RandomTile with a time variation of 50 frames, Scale variation and Rotation Variation of 1. As each tile has its own scale, rotation and time offset, they will all appear to be moving around independently. If your global range is 1-100, extend the animation at least 50 frames beyond each end of the timeline to get the best result. For quick results, use my tool AnimationMaker to generate a continuous animation curve. With a noise wave you could easily make a bunch of wobbling bacteria or buzzing insects. A slow meandering animation and you could perhaps make snow or dust particles without going into 3D.

To give the illusion of distance, you have the option to ‘stack’ the tiles with the smallest at the back and larger ones in front (closer to the camera, as it were). You also have the option to generate a depth matte, based on the size variation, so you can add a ZBlur at the end to introduce depth of field, or use it to grade smaller/larger ones differently. Here’s an example of a simple buttlerfly image using those options:

…and here’s a look at another example of the depth matte created:

3) Make a random stylised version of a second image using embossed tile shapes. It also gives you the option to plug in a second ‘Source’ image and instead of using the tile’s original colour, each tile takes its colour from the average colour at that position on the second image. The result is, when each tile is put together, it builds the second image, in a pixellised/mosaic kind of way. You also have the option to emboss each tile to give it more texture. Here’s an example using the colourwheel and a photo:

4) Create a ‘painted’ version of a second image by using various brush shapes as tiles. Circles are one thing, but if you grab a brush stroke image from somewhere and use the above method, with some playing around and choosing different sizes and options you can create coloured brush strokes to make up the second picture. The best thing is, as RandomTile preserves the alpha of each tile, you can make several RandomTile nodes using the same Source image, but different brush shaped tiles, and merge them over each other. There is also the option to provide a Distortion Map, which distorts each tile before the colour is applied to it. So, give it a lumakey of the photo and the brush strokes will be persuaded to shape themselves to the photo more. Here’s a quick example I did using the above photo:

First, use broad strokes for the base.

Then block in the main areas with some large dabs of paint.

Now some medium sized strokes to bring in more detail. With a little embossing.

Now some thin horizontal strokes.

And finally some wispy strokes for good measure.

Slap them all together, and you get a painting.

This is a quick example I put together, there are no doubt many ways to do this.

There is another very handy option which I didn’t use in this example: provide a Weighting Map; either some kind of lumakey, or hand drawn with rotoshapes. You then have the option to recalculate the position of all tiles and have more of them cluster around the white areas of your Weighting Map than the darker areas. So, if you wanted to concentrate the smaller detail strokes in the centre of the screen, perhaps where a person is, you just draw a white shape there and press the Adjust For Weighting button.

So anyway, a photoshop-style painting effect using nothing but standard nuke nodes. You will need a pretty powerful machine though if you want to use many thousands of tiles. The above was fairly taxing on the high spec linux box I used, but it wasn’t that slow considering there are about 5000 tiles in total (approx 50,000 nodes internally, all linked up in a complex script with expressions and everything). The creation of a RandomTile node takes a little while, but the above frame only took a few seconds to render. This tool is free to use at your own risk; if your machine starts to smoke as a result of using it, I take no responsibility 😉 I’ve tried it on my 3-year-old iMac at home and it runs fine, but is noticeably slower than the production linux box when you start using more than 1000 tiles.

What does a complex script with 50,000 nodes in it look like? Well, I can’t tell you, because Nuke allows you to generate insane scripts inside a group using python, but woe betide anyone who tries to open the group to have a look inside. But, as I can just put all the controls on the outside, there’s never any need to open the magic box.

5) Create a moving ‘painting’ by also providing distortion and ripple maps based on the plate. Now, a pretty painting effect is fine, but applying it to a moving image is probably what you want. I’ll be frank, it’s hard to achieve decent results because if the tiles were somehow regenerated on every frame, you’d get horrible flickering and it’d be a mess. If they don’t move at all (the default for RandomTile), it’s better, but the image would seem to move behind the strokes, like looking through a stained glass window. I have come up a couple of solutions that are somewhere in between: Provide a lumakey or roto of the plate as a Distortion Map as mentioned above. This way, when things move behind the strokes, the strokes themselves get smooshed around a bit. Combine that with the further option of providing a Ripple Map and with some playing around you might get something that works. The Ripple Map is again perhaps just a high contrast luma key of the plate. When a tile is over a white pixel it moves up and right a set amount, when it’s over a black one, it’s back to the original position. As a gradient moves behind it, it will move more as it gets brighter. The upshot is, as a bright object moves around underneath, a ripple is sent through the tiles as it passes beneath them. Will need experimentation, but I had a play around and it gave an interesting result.

Get RandomTile here. The zip file contains the .py file containing all the functions, the icon and an example menu.py file showing you how to set up a button in the toolbar. If you find it useful or fun, let me know. I’m sure people can come up some inventive ways to use it.

## Using waves to drive animation in Nuke

Creating repeating or random patterns in the curve editor can often be made easier by using expressions that describe a curve. Sine, noise and random functions are very useful, but forcing them into the exact shape you want can be a little time-consuming. So, following my previous post talking about my gizmo WaveMaker, I thought I’d share some handy expressions it uses which you can copy and paste straight from this blog when you need them, rather than installing the gizmo itself.

Edit on 12/10/2013: I have just released Animation Maker, a handy Nuke extension that contains all the waves talked about here, plus lots of Ease curves too. See the article here.

Click on any value in any node, press ‘=’ and type an expression. Right click and choose ‘Curve Editor…’ to view the curve.

These expressions give you full control over the width, height and position of the wave. Either replace the following variables with your actual values, or add your own sliders to the node so you can adjust them on the fly (see below for how to do that).

waveLength (how many frames between peaks of the wave)
minVal (the wave will never go below this value)
maxVal (the wave will never go above this value)
offset (shift the wave back and forth in time)

Edit on 15/01/12: I have also provided simple versions that will work immediately once you paste them in. They will just produce a wave between 0 and 1 but that may be all you need.

## Some useful wave expressions:

### Sine

(((sin(((frame*(pi*2/(waveLength/2))/2)+offset))+1)/2) * (maxVal-minVal) ) + minVal

Simple version:  (sin(frame/5)/2)+0.5  (Wave between 0 and 1, replace the ‘5’ to adjust speed)

### Square

((((sin(((frame*(pi*2/(waveLength/2))/2)+offset))+1)/2) * (maxVal-minVal) ) + minVal) > ((maxVal/2)+(minVal/2)) ? maxVal : minVal

Simple version:  (sin(frame/5)/2)+0.5 > 0.5 ? 1 : 0  (Wave between 0 and 1, replace the ‘5’ to adjust speed)

### Triangle

(((((2*asin(sin(2*pi*(frame/waveLength)+offset)))/pi) / 2)+0.5) * (maxVal-minVal) ) + minVal

Simple version:  (((2*asin(sin(2*pi*(frame/30))))/pi) / 2)+0.5  (Wave between 0 and 1, replace the ’30’ to adjust speed)

### Sawtooth

((1/waveLength)*(((frame-1)+offset) % waveLength) * (maxVal-minVal) ) + minVal

Simple version:  ( 1 / 30 )*( (frame-1) % 30)  (Wave between 0 and 1, replace the two ’30’s to adjust speed)

### Random

((random((frame/waveLength)+offset)) * (maxVal-minVal) ) + minVal

Simple version:  random(frame/5)  (Wave between 0 and 1, replace the ‘5’ to adjust speed)

### Noise

(((1*(noise((frame/waveLength)+offset))+1 ) /2 ) * (maxVal-minVal) ) + minVal

Simple version:  (noise(frame/5)/2)+0.5  (Wave between 0 and 1, replace the ‘5’ to adjust speed)

### Bounce

((sin(((frame/waveLength)*pi)+offset)>0?sin(((frame/waveLength)*pi)+offset):cos((((frame/waveLength)*pi)+offset)+(pi/2))) * (maxVal-minVal) ) + minVal

Simple version:  sin(((frame/10)*pi)) > 0 ? sin(((frame/10)*pi)) : cos(((frame/10)*pi)+(pi/2))  (Wave between 0 and 1, replace the ’10’s to adjust speed)

### Sawtooth (parabolic)

((sin((1/(pi/2))*(((frame-1)+offset)/(waveLength/2.46666666)) % (pi/2)))>0.99999? 1 : (sin((1/(pi/2))*(((frame-1)+offset)/(waveLength/2.46666666)) % (pi/2))) * (maxVal-minVal) ) + minVal

### Sawtooth (parabolic, reversed)

((cos((1/(pi/2))*(((frame-1)+offset)/(waveLength/2.46666666)) % (pi/2)))>0.99999? 1 : (cos((1/(pi/2))*(((frame-1)+offset)/(waveLength/2.46666666)) % (pi/2))) * (maxVal-minVal) ) + minVal

### Sawtooth (exponential)

((((((exp((1/(pi/2))*(((frame-1)+offset)/(waveLength/4.934802)) % pi*2)))/534.5)) – 0.00186741)>0.999987? 1 : (((((exp((1/(pi/2))*(((frame-1)+offset)/(waveLength/4.934802)) % pi*2)))/534.5)) – 0.00186741) * (maxVal-minVal) ) + minVal

*Note: the waveLength value doesn’t really correspond to the peaks in Random or Noise waves, so you will probably need a smaller wavelength value for those.

1. Right click your node, choose ‘Manage User Knobs…’
2. Click ‘Add…’ and choose ‘Floating Point Slider…’
3. Type ‘waveLength’ into its name and label boxes. Give it a max and min value of 0 and 100.
4. Repeat with each of the four variable names (above).

These  four sliders will appear in the ‘User’ tab of the node. You may find it better to create a ‘NoOp’ node, add the above sliders, but also add several extra floating-point sliders called ‘Wave1’, ‘Wave2’, ‘Wave3’ etc. This way you can use the same sliders to control several different expressions, then you can use any one of them to drive animations in your script.

It’s worth noting many of these wave shapes can be created using a few keyframes and telling nuke to ‘loop’ that section. But using expressions with a few sliders you can mess around with them a lot easier. Besides, maths is fun.

## One more thing:

To describe a CIRCLE, put this in the X:

(((sin(((frame*(pi*2/(waveLength/2))/2)+offset))+1)/2) * (maxVal-minVal) ) + minVal

and this in Y:

(((cos(((frame*(pi*2/(waveLength/2))/2)+offset))+1)/2) * (maxVal-minVal) ) + minVal

Simple version (X): sin(frame/5)*300

Simple version (Y): cos(frame/5)*300

(replace the ‘5’ to adjust speed, replace the ‘300’ to change the circle size)

Tip: put it in the X and Z in a TransformGeo after a Card to make a carousel type animation.

## WaveMaker v3

I’ve added a few more gizmos and python functions to davidemeny.com, feel free to use them as you wish.

Edit on 12/10/2013: This tool has been superceded by my new tool Animation Maker.

One of which helps you generate waves in the curve editor:

## WaveMaker v3

Animating flickering lights or continuous movement is a doddle in Nuke if you know how to generate sine waves, noise waves etc in the expression editor.

For example: a simple sine wave ranging from 0 to 1 with a wavelength of n frames would be “=sin((frame/(n/2))*pi)/2+0.5”. For the maths geeks, whipping up expressions is second nature, but for many of us it’s a hassle to remember all the various combinations when we just want a thing that goes up and down in a repetitive or random way.

WaveMaker gives you a choice of a variety of handy wave shapes, lets you put in a minimum and maximum number, gives you a ‘Speed’ slider, an ‘Offset’ slider and then you just press ‘Generate’ to write out whatever complex expression you need to make that wave. Just link the ‘Result’ value to whatever you want to control and you’re away.

It also lets you use a second, slower wave to affect the other wave. For example, you have a high frequency pulsing noise wave but you want it to fade up and down in intensity over time. Just use a slow sine wave and tick the ‘use modulator wave’.

With version 3, I have now added a ‘squarify’ tick box, which converts any wave you come up with into a square wave version. I have also added loads more wave types, including TRIANGLE and SAWTOOTH.

Have a play around, you can make some pretty weird looking waves. This isn’t a gizmo you will use all the time, but when you do, it’ll save you a lot of time writing long expressions or creating lots of keyframes.

## Nuke: Making Stereo Noise

After seeing the Foundry tweeted a tutorial on converting a 2D image of fire into a stereo image today, I wondered if you could use a similar method to generate stereo noise clouds within nuke.

Here’s a script I knocked up this evening very quickly to demonstrate the idea, please feel free to expand and improve on this!

1. Set your new project to have stereo views (in the Project Settings).
2. Make a Noise node. By default it generates a nice cloudy texture.
3. Split off the alpha channel, invert it, then copy it back into the forward.u channel
4. Make an iDistort node, set the channels to RGB, the UV channels to motion (and just check the u box), set the UV scale to 15 or so.
5. Make a JoinViews and plug the iDistort into the left side and the original Noise into the right
6. Stick an Anaglyph node under that and put on your red/cyan glasses to view your noise cloud in wonderful stereo.

This uses the motion channel values to distort the image horizontally; the black (0) areas have no effect, and the white (1) areas distort fully, and all shades in between. So that has the effect of pushing the white ‘peaks’ to the left, while keeping the black ‘valleys’ where they are. Giving the illusion of depth when viewed in stereo.

It’s not really like smoke, because you can’t see the other side, but perhaps a combination of several of these could simulate it better? Suggestions welcome.

If the noise isn’t animating, and you use the translate tab to move the noise around, you get the illusion of looking down onto a bumpy landscape with peaks and valleys. Could be useful.

Will play with this more, it may not be of much use but feels like there’s potential there for generating stereo elements to put onto stereo live action (if you can’t get hold of real elements, of course).