Chops are weird. Its the scary corner of Houdini no-one talks about, the documentation is sparse, and artists who understand it walk around in a smug world of their own. Bastards.
Every 6 months or so I'll have a stab at it, and while I could follow along with tutorials, it never clicked in the way sops clicked or even dops, and dops are weird.
Well, with the advent of the channel wrangle and some help from discord (especially Henry Dean, who in one video did more to advance chops knowledge than 10 years of prior work), I think I've had that click moment, so I'm hastily writing it down before it fades away.
So what the hell is chops?
The standard analogy is 'audio processing', but there's a few other things chops does, handy to be aware of them all.
- Chops is a digital audio processor. Load in wav files, midi files, filter them, generate triggers to spawn particles or drive animation, all that is well covered.
- Chops is a rigging toolkit. Feels like this will get more attention going forward, but already a lot of the rigging and constraint tools are done via chops. Dynamic parenting, Euler rotation filtering and cleaning, aim at constraints, IK handles, all that sort of stuff is chops.
- Chops is a way to model and sculpt animation independent of time. That last one is my value-add analogy, lemme explain the only way I know, gifs.
Here's a bouncing ball:
In other 3d packages you can display the motion path (here I've faked it in Houdini):
Now imagine that motion path was a regular curve in sops. Ideally you would be able to model and distort the curve, and have the animation update. You wouldn't be limited to whatever tools the keyframe editor allows, you'd bring the whole sops toolkit to your animation workflow. What you've also done is stop looking at time through the timeline, you can now manipulate all moments of the animation at once. All the animation is splayed out in a human readable format.
This is what chops does, not just for translation like the sphere above, but for all animatable parameters, and not just for a single position, but for all the point animation on a complex shape, or all the joints in a rig, or all the things that are changing over time (within reason!).
How to setup a chopnet for sops
I hope you agree that all the fun stuff happens in sops. So its surprising that you have to jump several hoops to get sops to talk to chops. The steps are:
- Define a node where you want chops to read from, usually a null with an obvious name
- Append a channel node to read the data back from chops, set its method to 'animated'. This will be in an error state until you give it a chopnet and a chop out node to read from.
- Create the chopnet, dive inside
- Create a geo node to read from the null from earlier, set its method to 'animated' too
- Append a null to be the export location, name it nicely
- Go up a level, select the channel sop, set the path to the chop null (eg '../chopnet1/OUT') set its mode to animation
- Have a drink
Here's my best speed run. Ready.... GO:
Deciphering the motionfx graph
So... what have we done? A geo chop reads @P by default from sops, but by default only on the current frame. Switching the method to animated will read the full timeline animation. If you create a motion fx pane, you'll see all the animation data graphed out, much like an animation view. It'll probably look super busy too, if you hover over the pane and tap L on your keyboard, it'll hide the labels and make things run a little faster.
I've taken a line with 10 points, and in a wrangle set it to wave back and forth along x with a simple @P.x = sin(@Time);
Here's how that looks next it its motion fx graph:
I've left the labels on here, you can see the sine wave motion on the blue, well, sine wave. The 80s pink+purple lines are the y positions of each point; they don't change, so they all stay as flat lines. What you can't see is tz; all the points share the same tz value, 0, so they're all hidden at the 0 point.
What's all this tx/ty/tz stuff? Look at the geometry chop, you can see it has an attribute scope, P, and a rename scope, tx ty tz. Unsurprisingly, this takes each component of @P, and renames them as tx ty tz. I suspect this stems from a few things; chops is old and does its own thing compared to the rest of Houdini. Also I think its original purpose was to deal with object level transforms, where those keyframeable parameters are called tx ty tz, rx ry rz, sx sy sz.
Note that on the channel sop, it does the reverse, reads in tx ty tz, and converts them back into P.
The spring chop
So say we limited the sine motion to a single pulse by clamping time (and speeding it up so its more interesting) : @P.x = sin(clamp(@Time,0,1.57)*4);
Inside the chopnet we can add a spring chop, and get some cool stuff (excuse the size of this gif, but its handy to see all the things):
It's important to remember that that isn't a simulation; it's better to think of it as a deformer, for motion. Note that I can change the properties like mass, decay etc, and the graph updates in realtime. There's no run up, no recaching, no sim. That's kind of cool. What else can we do?
Stagger channels with a wrangle
Download scene: File:chops_example.hipnc
Now that we have the channel wrangle in H16, we can do some fun stuff.
Each line of animated data is called a channel, within chops they're kind of like a packed prim for animation; they're an atomic unit, they have attributes, and have sub-data (kinda like unpacking a packed prim, don't think about this analogy too much).
In a wrangle context, the important attribute names are V for a value at a given time, C for the channel number, and a few other helpers like CN for the channel name, They're all listed here: http://www.sidefx.com/docs/houdini/nodes/chop/channelwrangle#globals
There's not a lot of chops specific vex functions, but the ones they have are useful. A handy one pointed out by Heny Dean is chinput(), which is sort of like a point() call, it lets you access other channels and other values of those channels.
So here, lets take this boring back and forth motion, and do something cool; stagger each point based on its channel id. Insert a channel wrangle after the geometry chop with this code:
V = chinput(0, C, I + C*ch('offset'));
Click the button to make a slider, slide it while watching the motion fx window (and the viewport):
I remember doing lots of keyframe anim like this in maya, keying many objects to move in lockstep, then in a dopesheet window offsetting each object by a few frames to get a sexy staggered motion. And here's houdini doing it procedurally. Oh the time I've wasted....
Dynamics driven by dops
Download scene: File:chops_drive_dops.hipnc
Download mp3: File:beat.mp3
A more stereotypical example of what people think of for chops. A mp3 beat is driving the vertical motion of a ball. The ball has its motion transferred to a grid, which then drives a ripple solve. The ripple solve is in turn used to drive a particle sim. To make the gif make sense, I also drive a line using the same mp3 like an oscilloscope, but unlike an example elsewhere on this site, this is using a channel wrangle.
Nothing overly complex here, but when getting into this sort of stuff it can be hard to know where to start, hopefully this give some clues.
Using the beat chop
The beat chop works like a metronome, and like most audio editors you can tap a beat and it'll then guess what beats-per-minute you've tapped. It expects 2 input channels, 'listen' and 'tap'. If listen is non-zero, it tries to work out the bpm from pulses in the tap channel.
You can generate those channels with a keyboard chop, holding down a key to enable listen mode, and tapping another key to set the beat. To allow the keyboard chop (and other input chops) to detect keyboard presses, you press the scroll-lock key. The time indicator will turn orange to show that chops is now in detect-inputs mode. So:
- keyboard chop, name first channel 'listen', second 'tap', leave the keys as 1 and 2 if you want
- connect that to a beat chop
- hit scroll lock, see the frame indicator turn orange (I had to use a virtual keyboard, no scrolllock on my mini laptop keyboard)
- hold down 1 to enable listen, tap 2 to set the beat
I'm using an on-screen keyboard tool partially so you can see what I'm doing, but mainly because the little surface pro 4 I'm using doesn't have a scroll-lock key. :)
Before you go and chop all the things:
- Geometry chops don't scale well. Makes sense really; if you have a 50x50 grid over 240 frames, then that's 50 * 50 * 3 channels it has to generate ( 7500 ), times 240 frames = 1,800,000 bits of data. Remember if you want to access the entire timeline of animation at once and manipulate it, then all that has to be available, then all of _that_ has to be modified as you slide values on the spring chop. Made worse because...
- Chops are single threaded, or were last I checked.
- Chops can lock Houdini super easy. All those channels, all that data, put down some fancy chop, you'll pay for it.
- Chops are disliked and feared by most Houdini artists. Remember I said chops savvy folk get all smug? Part of that is knowing if they have to share their scenes with others, there'll be tears. Don't be a dick, keep the chops stuff to only when you really need it.
- https://vimeo.com/209784546 - brilliant clean simple tutorial from Henry Dean, covers the rigging side of chops better than anything else I've seen.
- http://www.technical-artist.net/?tag=tutorial - japanese, google translate does a pretty good job. Covers using chops as cheap mocap source among other things.
- http://www.andrew-lowell-productions.com/andrew-lowell-productions/resources.html - quite old, but still a great resources for the audio and midi side of chops.
- http://www.hossamfx.org/chops-in-houdinifx/ - The trailer for this training video looks pretty good (I haven't watched it though)
- http://www.derivative.ca/ - The guy responsible for chops split from Sidefx several years ago, and spun chops into a realtime gfx toolkit called Touch Designer. Chops is the gateway drug to Touch Designer (or maybe Touch is the gateway drug to Houdini?), either way if you like chops, you'll love Touch. :)