From cgwiki


chramp can be a much more direct and visual way to shape things. If you've used the curves tool in photoshop this will be intuitive, if not, I'll need a few gifs. :)

A channel ramp gives you a little 0-1 xy graph. You can click on the graph to edit the shape of it, with options for if the points on the curve are angular or curved, or stepped, or any combination thereof.

Within your code you tell it a variable that will become the x-axis of the graph, and it will return the corresponding value from the y-axis.

Eg, in its default state its a linear graph; 0 maps to 0, 1 maps to 1, its all clean (note that values below 0 or above 1 get clamped):

Ramp default.gif

To invert values, you make the graph slope the other way:

Ramp reverse.gif

Or you can do a sine wave (well, sort of):

Ramp sine.gif

Or random whatevers:

Ramp randomish.gif

Chramp and waves

Eg, to alter distance from the previous lesson:

 float d = length(@P);
 d *= ch('scale');
 @P.y = chramp('myramp',d);

So we specify the name of the ramp (myramp, but it could be anything), and what will be used for the x-axis, d in this case.

At first you'll probably see a weird multiple wave pattern. Adjust scale so that you get a single wide wave that fits the entire grid.

Now have a play! Invert the ramp so that it starts high, ends low. Click a few more points within the ramp, change the shape. Make a rough sine wave just using the ramp. Now change the scale slider again, see that it repeats (kind of a misbehavior that chramp has an implicit modulo, explain that a bit)

Add time to the mix (by subtracting it so it moves in the way I expect), plus a scale control, now you have a way to define time based waveforms:

 float d = length(@P);
 d *= ch('scale');
 d -= @Time;
 @P.y = chramp('myramp',d);
 @P.y *= ch('height');

Here's a little demo. See how if I clip the grid in 2, the cross section shows its repeating the chramp shape. By changing the scale (ie width) and the height sliders, I can set how often the ramp repeats, and after that point, can dial in whatever shape I want. Triangle waves, square waves, square waves with soft falloffs, increasing triangle waves, a badly drawn sine wave etc etc This make it very easy to dial in the shape you want.

Chramp waves demo.gif

Note that by 'easy' I mean 'easy until you start swearing at the ramp UI'. It doesn't let you view outside the 0-1 range, changing the curve point types to values other than linear can get twitchy, you can't easily copy and paste between 2 different ramps, and there's a million other little irritating issues, and yet.... it's still pretty cool.

While mapping a linear ramp to a value is nice and direct, you shape any input value to any output value. For example, taking the perfect wave generated by sin, and clipping or shaping it to change the result:

 float d = length(@P);
 d *= ch('scale');
 d += @Time;
 d = sin(d);
 d = fit(d,-1,1,0,1);
 @P.y = chramp('myramp',d);
 @P.y *= ch('height');

Chramp sin fit.gif

Note that I took the value of sin which was between -1 and 1, and fit it to go between 0 and 1. Chramp is less confusing when the input is kept in this range. In fact a lot of vex functions expect this, when values are put into the 0 to 1 range they're called normalized values. This is especially important for vectors, which we'll get to in later lessons.


  1. Create sawtooth waves, triangle waves, square waves
  2. Affect colour in this way to make a shape pulse with pleasing colours
  3. Do this to the different colour components at different rates, get trippy
  4. Affect colour and position in different ways, find the most interesting way to break the pig. Keep all the effects controllable from channels.

prev: JoyOfVex3 this: JoyOfVex4 next: JoyOfVex5
main menu: JoyOfVex