Gen Tutorial 2b: Adventures in Vectorland

The jit.pix-based patches we created in our last tutorial do cool things and use patching techniques that will probably be accessible to the average Max user, they’re not all that they could or should be as Jitter Gen patches.

Don’t get me wrong – they make sense and introduce the idea of swizzling data from a vector in the Jitter Gen world. And they work just fine as patches. But one of the things that’s really cool about working with Jitter Gen objects has to do with working with vectors as you patch.

In the Jitter Gen universe, the vector reigns supreme, and we’re going to take this tutorial to get you used to the idea of thinking in terms of vectors as collections of data (as opposed to the individual bits of data we worked with in the first of these two tutorials), and show you how to patch more fluently and efficiently.

If you’re a beginner, thinking in terms of vectors involves developing some simple habits of thought about how to combine, split, and recombine data as you patch. To help you along, we’re going to take some of the patches we created in Gen Tutorial 2a and rewrite them so that they make use of vectors and are more “gen-like” and efficient. In many cases, the resulting patches will be a good deal more compact.

One of the first things we mentioned in describing the Jitter family of Gen objects is that the jit.pix and jit.gl.pix objects both operate on matrices that represent 2d images.

As a result of their image orientation, these two objects allow us to do something interesting – when we work with vectors, we often don’t need to use the vec operator at all when patching. In some cases, we don’t even need to swiz out individual bits of data. If we operate on aggregate data, we can take example of some special features of the jit.pix and jit.gl.pix objects.

My First Vectorization

In the Gen Tutorial patch colormap_3a, we took a patch that originally operated on aggregate input data and swizzed out the individual color values (r, g, b, and a) in order to be able to set parameters for the red, green, and blue planes individually for greater variety. Here’s what’s inside of the colormap_3a tutorial patch’s jit.pix object:


View the full-sized screen shot.

You’ll notice that the patch is composed of three sections, each of which has a swiz operator at the top. When a new matrix/vector arrives in the in 1 input object, the red, green, and blue values are unpacked/swizzled.

Each of these values is a floating-point number in the range 0. – 1.0, and the three portions of the patch process each color value independently of the others using the same logic.

At the very bottom of the patch, you’ll see a vec operator, which we used to pack the individually manipulated parameter values back together into a vector for output.

When we did all this duplication, all we needed to do to accommodate the additional channel processing was to change the names of the param operators when we duplicated the functionality from our earlier tutorial patch.

That’s fine as far as it goes, but it doesn’t go far enough.

So far, I’ve talked about the swiz/vector pair as operators that work like the Max pack and unpack objects – they provide a way of taking a group of data and breaking it up into individual pieces that you can modify individually and then repack and send on their way. Introducing the process in terms that most Max users can quickly grasp may make experimenting in Gen seem a bit less scary, but it’s not the whole story. The patches in Tutorial 2a were correct and worked properly, but they didn’t take full advantage of the ability of working with vectors in Gen.

It’s been my experience to date that people encountering Jitter Gen objects for the first time initially find vectorization confusing, but it’s really not that difficult to get used to. The original patch is a perfectly legitimate way to do color mapping and it will work fine when used inside of a Gen patch. But look more closely – you’ll notice that there are three collections of Gen operators that are performing the same kinds of operations on the red, green, and blue portions of each pixel in the image.

Even though we might be working with different parameter values and settings for function and inversions for each of the three colors, the calculations we perform and send to the vec operator are the same in each case – only the parameter names are different.

When we work with vectors in Jitter Gen objects, we can combine the set of three similar calculations into one calculation where all three color channels are processed in tandem by treating them as a vector (you might want to think of the vector at this point as a list that contains three values). When we do that, each Gen operator down the line then performs a calculation on each of the color values contained in the vector. Once we regroup things in this way, each parameter in our our patch will take three three-item lists as inputs, where each list contains the parameter values associated with each of the three colors.

So how do we do that? First, we modify the param objects that provide the interface to the patch. In place of the three param objects for the modes we want to apply for each color, we create a single param object with three arguments (param mode 0. 0. 0. ). This operator describes the vector we’re working with as having three items and also sets their default values. Similarly, we group the amp parameters that set the values we’ll feed to the sine or cosine operator (param amp 2. 2. 2. ). Finally, we can replace the inversion parameters with a single param object with three args that will, by default, set our patch to pass its input in unaltered form (param invert 0. 0. 0.).

Tutorial patch colormap_3b shows what our vectorized patch looks like. It’s a lot simpler, once you understand how we can combine operations into vectors.

In addition to our combining operations into vectors, you’ll notice that the vectorized patch no longer contains swiz or vec operators. You’re seeing a neat feature of the jit.pix and jit.gl.pix objects in action – since we’re swizzing out the red, green, and blue values as a single vector and operating on that vector, we don’t really need to unpack (swiz) or pack (vec) it up – we just pass the vector through the patch logic and output the result.

The clever reader may be wondering why it is that there’s no reference to the image’s alpha channel in sight anywhere in the patch. That’s because the jit.pix object has a particularly useful feature – If you send a three-element RGB vector to the out 1 operator, the jit.pix object will convert it to an RGBA value by automatically adding an alpha channel with a value of 1.0. Sure makes things easier, doesn’t it?

Gen Tutorial 2b: Adventures in Vectorland

Feb 4, 2012 at 2:36pm

Hi,

nice tutorial. Interestingly, Y get marginally better performance (a couple of fps more) in swizzlemap_1a than in swizzlemap_1b. May be due to that couple extra multiplications?

#260577

You must be logged in to reply to this topic.