Getting Started with Jitter Geometry
The jit.geom
family of objects, like jit.geom.shape, are a specialized group of Jitter objects designed to work with Half-edge Geometry Structures. We'll talk about some of the details later, but for now the most important thing to keep in mind is that this way of representing geometries makes certain kinds of geometry manipulations much easier and more efficient:
- Generating shapes - Use jit.geom.shape to create simple geometries with an arbitrary number of subdivisions.
- Vertex adjustment - The jit.geom.remesh object lets you rearrange the vertices of a geometry, making them more evenly distributed without changing the overall shape. You can add and remove vertices with jit.geom.subdivide and jit.geom.decimate.
- Transformations - Smooth out a geometry with jit.geom.smooth, add roughness or procedural displacement with jit.geom.dimples and jit.geom.displace, or perform more radical transformations with jit.geom.twist, jit.geom.waves, and jit.geom.xform.
- Property generation - Create dynamic, adjustable shapes with lifelike surface properties, using jit.geom.texgen and jit.geom.normgen to generate texture coordinates and surface normals.
Making a Shape
Open the patch geom-01.maxpat
.
When you first look at this patch, you'll notice something brand new: a striped, red patch cable connecting from every jit.geom
object. This cable carries half-edge geometry. As you can see, the jit.geom.shape object creates simple 3D forms, very similar to the jit.gl.gridshape object. However, if you take a close look at the default shape, the icosphere, you'll see that it looks very different from the "sphere" shape generated by jit.gl.gridshape.
In fact, the name of this geometry—icosphere—describes the equal distribution of points around the center of the sphere. Now, try changing the value of the @divisions
attribute on jit.geom.sphere. Notice how the number of faces changes.
If you look carefully, you can see that every time you increase the number of divisions, you're dividing each face into three new faces. This is a big clue as to how the half-edge geometry is working under the hood. The real power that the half-edge representation gives us is that each vertex "knows" something about which vertices are adjacent to it. So, it's relatively easy to add more vertices relative to existing ones.
Making Normals
Now, try changing the @type
of jit.geom.normals to something other than face
. You should see the shape change to something nice and smooth.
Unlike jit.gl.gridshape the jit.geom.shape object doesn't generate surface normals. Without these normals, the graphics engine doesn't know the orientation of the object's surface. An object with no surface normals always looks completely flat, no matter how it's lit.
The reason jit.geom.shape object doesn't make surface normals is so that you can do this step on demand after you've transformed the geometry of your shape. If you've ever tried to distort the surface of a geometry from jit.gl.gridshape, maybe you've noticed that it looks weirdly flat.
This is because moving the vertices around doesn't change the surface normals, so it doesn't change the orientation of the faces between the vertices. Later versions of Max added the @auto_normals
attribute to jit.gl.mesh, which gets around this somewhat. However, jit.geom.normgen is an even more flexible approach.
Finally, you'll see that we're connecting the output of jit.geom.normgen into an object called jit.geom.tomatrix. This converts from geometry back into a matrix. By default, this object will also compute surface normals, so we've added @auto_normals 0
to make sure that only jit.geom.normgen computes these normals.
Asynchrony
Now, try setting the number of divisions to something really high, like 8. If you don't see any change, try setting @divisions
to 9 or 10. Eventually, you should see Max stall a bit (it's a lot of computation), and you'll see the appearance of the jit.geom.normgen and jit.geom.tomatrix change to look something like this:
By default, the Jitter geometry objects are asynchronous. That means that when you change their attributes or send them a new geometry, the result doesn't come out of the object's outlet right away. This is done in order to avoid blocking the rest of the Max application during an expensive computation.
Wrapping Up
In this quick intro to Jitter Geometry, we looked at the jit.geom.shape object for creating simple geometries, and the jit.geom.normgen object for generating surface normals. If you want to have a little bit of fun (just a little, not too much), click the toggle in the top-right of the patch.