Friday, February 10, 2012

UV Space Creeping


This is a neat trick I used on a few projects. It involves moving particles along an object's UV space so that they creep nicely along the surface of the object. It works well for still objects and animated characters.

The first step is to prepare your model with proper UVs. The UVs will be of vertex type. It is recommended that none of the UVs overlap.

Next, you need to "cut" the geometry based on the UVs. Use a VertexSplit SOP and use the uv attribute.

In Houdini, you have points and vertices. Points represent the position, XYZ, in 3 dimensional coordinates and the vertices can also represent the position in 2 dimensional UV coordinates, or texture space, UVW. So you can have multiple vertices that are in the same position as their corresponding point in 3D space, but have a completely different position in texture space.

So what the VertexSplit SOP will do is split the points on the geometry if its vertices are far enough distance from each other in UV space.

The next node you need is a Rest SOP. This will simply create a point attribute that is equal to the position, P, at that frame.

Finally, you need to use a Point SOP and set the position of each point to equal the position in UV space, $MAPU, $MAPV, $MAPW.

So now what you have is a 3D geometry that mimics the 2D UV mapping. If you bypass the VertexSplit, some of the primitives may have been stretched because of the connectivity, and you don't want that. And your rest attribute will remember the original position of each point at a given frame. We will use this later...

In a separate tree, lets create a simple particle system that emits particles in a 2D fashion. They can just be saved to disk.

Now take these particles and move them to the side in Z slightly and set a Normal, N, to (0, 0, -1).

The next step is to use a Ray SOP to project the particles onto our 3D UV geometry. The normals will direct the particles onto the shape.

There will be particles that miss the geometry. Check on 'Create Point Group' to group the successful hits and later delete the ones that miss.

Back at the Ray, tell it to inherit the rest attribute from the geometry. Then use a Point SOP to set the position to $RESTX, $RESTY, $RESTZ.

Now we have particles creeping on the geometry based on the UV space. The rest attributes are pretty accurately approximated on the primitives as the particles are being projected, So it works particularly well with animated characters.

You may need to use UV Transforms to space out your UVs if some overlap.

Later you can use a fluid mesh or something on the particles.

You may need to inherit Normals from the primitives or velocity from the points.

You can also try projecting still curves for some interesting effects.