CHOPs Deforming Geometry: Part 2
Creating an Ocean Wave
Published: Monday, March 19, 2007

Video
CHOPs [34MB QT - 15 min.]

The LookUp CHOP

You were introduced to the LookUp CHOP in the last lesson. Let's create another example by looking at a simple example of an animated wave on a surface.

Create a network where you have a default Grid wired in to a Null SOP and reference this in to a local CHOP network with a Geometry CHOP. Then complete the CHOP deform engine by appending a Channel SOP to the Null SOP and reference it to a Null CHOP called OUT. Set up the channel1 Channel SOP to only work on ty. Or if you want, load in the starter example file:

LookUp CHOP Start File (Download .hip file)

Step 1: In SOPs, select the channel Channel SOP making sure it has the Display and Render Flags set and split your viewport top to bottom. Unlink the top viewport pane. The circle should have no number. Leave the bottom split viewer pane synced to the network.

Step 2: Dive in to CHOPs. Your interface should look exactly like the screen shot:

Step 3: Place a Noise CHOP to the right of the geometry1 Geometry CHOP. Open the Channel folder for the noise1 Noise CHOP and change the Channel Name to ty. This is important as the LookUp CHOP will return the name of the second input lookup channel and our Channel SOP is set to work with ty. You need to manage your channel names in CHOPs if you want predictable results. That goes for you power users as well.

Step 4: Insert a LookUp CHOP between the geometry1 Geometry CHOP and the OUT Null CHOP. You should get an error. The LookUp CHOP requires both inputs to have links in to it.

Step 5: Wire the noise1 Noise CHOP in to the right input of the lookup1 LookUp CHOP. Set the display flag to the lookup1 LookUp CHOP. The error flag goes away. Hit the "d" key with the cursor over the chop viewport to see the dot samples. We see a repeating pattern of noise in both the CHOP channel graph and the 3d viewport.

Step 6: Hold down the shift key and press the display flags for both the noise1 Noise CHOP and the lookup1 LookUp CHOP then home the chop viewport.

Notice that the resultant channel in the LookUp CHOP is the same length as the channels in the geometry1 Geometry CHOP. If you look closely at the general shape of the noise function and the resultant lookup channel, you can see that only a part of the noise channel is repeated. It's the part that is the same length as the incoming geometry. It's like a really low sampled version of the portion of the noise wave repeated over and over.

Step 7: Set the display flag on the geometry1 CHOP. In the CHOP graph pane, select the button along the top called "Graphs" and select the option "Graph Per Channel Name". Pressing on the "Graphs" button again, select the menu option "8 Graphs".

Step 8: Set the CHOP display flags to geometry1 and lookup1 CHOPs.

Now it's getting even clearer. The repeating pattern in the geometry1/tx channel matches up with the repeating pattern in lookup1/ty.

The repetition is actually quite simple to explain. The geometry1 Geometry CHOP has three channels: tx, ty and tz. The lookup1 LookUp CHOP is at it's default "Match By" setting of "Channel Number". That means that the left input's channel 0 or geometry1/tx is used to look up in to the noise channel noise1/ty sample value in to sample in time. Actually the help states that only one channel should be used as the left input to the LookUp CHOP but we'll leave things as they are knowing that only the first channel is used.

The left input sample values (in y) from zero to one map in to the right input Lookup Channels from start to end in time and return that value. For the left input channel, any values below zero are truncated to zero and any values above one are truncated to one. The remaining values between zero and one are used to index in to the lookup channel(s) as a percentage along it's entire length.

This gives us an easy way to index in to control curves. This is equivalent to the chf() expression function and gives us a set driven key type functionality.

The left input channel in our example, geometry1/tx, is a sawtooth wave that represents the position in x of each row in the grid. The value goes from -0.5 to +0.5. It is the value at the current sample being evaluated that looks up in to the LookUp channel which is noise1/ty. Since the sawtooth values go from -0.5 to +0.5, the negative values will be floored to zero and will always look up the very first value in the lookup channel(s). This explains the initial flat plateau in the resultant curve in the lookup1 LookUp CHOP.

The LookUp CHOP behaves completely differently than SOPs where the first input generally represents the geometry to work on. CHOPs is a whole different world where any input can provide the data to be passed on. We have to keep on our toes and make sure to read the help on each and every CHOP.

Working the Index Channels with Math CHOPs

In order to get control over the LookUp CHOP, we need to use one or more Math CHOPs to control the value range of the index channel. By scaling the channel values and combining them in various ways, we can get a lot of interesting results indexing in to the lookup table channel(s).

In this example, we want to change the range of the tx channel from -0.5 to 0.5 and get it to go from 0 to 1 so we can return the full lookup channel for each row of the grid.

Step 9: Insert a Math CHOP between geometry1 and lookup1.

Step 10: Go to the Range folder and set the From Range values to: -0.5, 0.5

Now we are sampling the entire noise channel for each row in the grid. Let's increase the resolution of the grid and see how the LookUp CHOP handles this. The last time we tried this with the Math CHOP approach, we ran in to all kinds of issues. Step 11: Jump back up to SOPs. Select the grid1 Grid SOP and change the number of rows and columns to 100 by 100.

This time we get a much better result: A higher resolution view of our noise channel drawn across each row of the grid. Now to introduce some variability in the Z direction of the grid. The easiest way is to combine the X and Z channels in to a single channel by summing them all up (since Y is a constant, it contributes nothing to the effect).

Step 12: Dive back in to CHOPs and insert a Math CHOP between the geometry1 CHOP and the math1 Math CHOP. Select it.

Step 13: In the OP folder of the math2 Math CHOP we just added, for the Combine Channels option select "Length".

Step 14: Go to the Multi-Add folder and drag the Multiply slider interactively. Play with the slider back and forth to see the various patterns you can create. End off with a value of 0.15. Set the display flag on the math1 Math CHOP and home on the channel.

Step 14 Hip File (Download .hip file)

Wow. By combining the three channels using length, we get the noise spread across the grid in a circular fashion. This is purely a result of our grid being oriented around the origin. Looking at the curve in the math1 Math CHOP, we see a set of scoops that index in to the lookup channel to create our concentric varying noise.

Working with the LookUp Channel(s)

The next step is to create more interesting lookup channels. Let's try adding a wave to the noise and feed that in to the lookup table right input of the LookUp CHOP.

Step 15: Tab-type add a wave CHOP and place it to the left of the noise1 Noise CHOP. Go to the Channel folder and rename the channel to ty. Change the period of the wave to 0.25 and the amplitude to 0.025. Let's animate the Phase with the expression: $FF*0.01 to give the wave some motion.

Step 16: To the wave1 Wave CHOP, RMB on the output and append a Math CHOP. Wire the noise1 Noise CHOP in to the math3 Math CHOP we just created.

Step 17: Wire the math3 Math CHOP in to the right lookup table input of the lookup1 LookUp CHOP.

Step 18: Select the math3 Math CHOP and change the Combine CHOPs field to "Add". Go to the Multi-Add folder and reduce the Multiply parameter to 0.2.

Step 19: Tame the noise down by setting the Harmonics to 1 and the Amplitude to 0.2. Add some motion by going to the Transform folder and add the expression to the tx parameter: -$T*0.1

Start moving the display flag around to see what the various CHOPs are doing to the channels in the CHOP channel viewer.

Translate the Wave Origin

The last major step involves translating the origin of the wave. Instead of relying on the grid's origin as the center point, we will use a Null Object to locate this center point.

Step 20: Jump up to Objects and tab add a Null Object.

Step 21: Move the null to -0.7, 0, -0.5

Step 22: Jump back to the CHOP network and add a Fetch CHOP and place it to the right of the geometry1 CHOP.

Step 23: Select the fetch1 Fetch CHOP and set the Node to /obj/null1 and change the Channels parameter to read tx ty tz.

Step 24: RMB Insert a Math CHOP between geometry1 and the math2 CHOPs.

Step 25: Wire the fetch1 Fetch CHOP in to the math4 Math CHOP we just added. Change the math4 CHOP's Combine CHOPs option to "Subtract".

Now we have control over where the origin of the wave effect will be. By subtracting the world Null object's position from that of the geometry's actual position, we can place the origin of the effect with the Null object. If you place the null far enough away, then you get fairly straight waves.

Play with this small network until you understand how it works fully. Here is my file with the above nodes renamed to properly reflect what they are doing in the network. Here's the file all worked up and ready to play with:

Simple wave lookup file (Download .hip file)

Some things to try with the example file provided above:

  • In the math__tweak_index_channel CHOP, change the minimum and maximum ranges to index in to the lookup table. Try value pairs of -0.1 and 0.5, -0.37 and 1.
  • Try different combinations of adding the Channels together in the math__combine_channels Math CHOP.
  • Animate the position of the null1 Null Object in tx and tz.
  • Place one of the cameras close to the water to get a nice rolling wave effect.
  • Try increasing or decreasing the resolution of the grid. Also try making the grid larger or smaller to see what effect it has on the Lookup CHOP.

Don't forget to hit play to see the waves animate.





User Comments
by digitallysane 2007-03-21 09:02:41
The industrial ambient sound is irresistible... and the information is again incredible.
by MADjestic 2007-03-22 16:27:47
Thank you, Jeff, for your great work! 
 
Looking forward to the continue of the CHOPs series ^_^
by masterK 2007-03-23 19:23:31
very good ... !!!!!!!
by mattd 2007-03-28 11:32:39
how about adding a pseudo-dynamic system to this? have a look at this, it would involve using a delay CHOP, but I cannot figure out how to implement a 3x3 kernal in chops 
http://www.gamedev.net/reference/articles/article915.asp 
MD
by edward 2007-03-29 23:31:20
The Filter CHOP will perform "blurring" but only in a single dimension. If you want to do something like the gamedev article, it's much easier to do in a VOP SOP where you use the neighbours to do the kernal.
by kuba 2007-05-13 09:03:50
I'm just wondering, why channel SOP is only accessible in Houdini master?
by kuba 2007-06-04 06:35:35
ok I was using escape 8.1, 8.2 seems to have complete list of chops :) (thanks SIDEFX)

Please login or register to add comments.