Matt's Source Code Portal

Home About Links Problems Cloth Contact

Rendering

Subdivision

The cloth structure can be easily rendered by using the triangle structure of the origional mesh. I tend to use a rather odd normal xyz to vertex RGB coloring scheme, because it makes it ovbious what the orientation of the cloth at any point is (and hence any inter-penetration is immediately noticed.) However, no matter what color scheme is used, it is nice to have a very smooth piece of cloth, without the need for millions of simulation vertices. Subdivisional surfaces is a very powerful algorithm to accomplish this; we can take a low-resolution cloth simulation output, and construct a high-resolution refined mesh. The result is only as accurate as the initial resolution, but the result is always a smooth surface. In the case below, I use the loop subdivision scheme.

20x20 grid with two fixed vertices. Left = No subdivision, Mid = 1 level of subdivision, Right = 2 levels of subdivision

We can see that even on a coarse grid, one level of subdivision makes the image incredibly smooth. Repeating the simulation on a 50x50 grid, again we see subdivision removing many nasty rendering artifacts.

50x50 grid with two fixed vertices. Left = No subdivision, Right = 1 level of subdivision

Quilting

With or without subdivision, our cloth still looks like an infinitely thin piece of paper. However many types of thin shells have a very visible thickness, such as a quilt or cotton sweater. Rather than simulating a thick piece of cloth, what we want is to take our infinitely thin output of the simulator and construct a mesh with thickness from it. Such an algorithm is relatively straightforward, given the right machinery. We first define a function f(x, y, z):

The surface f(x, y, z) = 0 is then "the set of all points a distance exactly T from the surface of the cloth." Once we can compute this function for any (x, y, z,) we want an algorithm that will give a triangular approximation of this surface and we are done. An algorithm that accomplishes this is called marching cubes, which divides the world we're trying to pologonize into a set of evenly spaced cubes, samples the function f(x, y, z) at each corner, and for cubes with some vertices with f(x, y, z) > 0 and some vertices with f(x, y, z) < 0, constructs a triangular approximation of the interior.

Left: Thin cloth input, Right: marching cubes output

Zooming in and looking at the wireframe:

Left: Thin cloth input, Right: marching cubes output

By increasing the resolution of the marching cubes, we can make the approximation as close as we wish. However, marching cubes does not give us a very uniform triangulation of the surface, and this is very problematic when we try to compute normals or render, as many triangles have almost zero area. To solve this, we first simplify the mesh producing many less vertices, and then we perform subdivision on the resulting mesh, finally refitting it to the original surface f(x, y, z). Both of these steps have a lot of work supporting them, but they are very well defined operations. Personally, I use my own subdivision code but invoke DirectX code to simplify the mesh to a desired number of faces/vertices. The results, shown below, is a very nice quilted mesh.

From left to right: Initial flat mesh, marching cubes approximation, simplified mesh, subdivision of simplified mesh

We can do many other tricks using this quilting; for example, if we define d(x, y, z) as the distance to a vertex on the initial cloth, rather than the distance to the surface of the cloth, we will get a "knot" at each source vertex. This can make for an interesting surface pattern, shown below, and many more can be achieved by allowing thickness to vary (and go to zero) across the cloth surface, creating holes and clumps derived from an input texture.

From left to right: Initial flat mesh, quilt with f(x, y, z) as distance to surface, quilt with f(x, y, z) as distance to vertex