Cg Programming/Unity/Nonlinear Deformations

This tutorial introduces vertex blending as an example of a nonlinear deformation. The main application is actually the rendering of skinned meshes.

While this tutorial is not based on any other specific tutorial, a good understanding of is very useful.

Blending between Two Model Transformations
Most deformations of meshes cannot be modeled by the affine transformations with 4×4 matrices that are discussed in. The deformation of space by fictional warp fields is just one example. A more important example in computer graphics is the deformation of meshes when joints are bent, e.g. elbows or knees.

This tutorial introduces vertex blending to implement some of these deformations. The basic idea is to apply multiple model transformations in the vertex shader (in this tutorial we use only two model transformations) and then blend the transformed vertices, i.e. compute a weighted average of them with weights that have to be specified for each vertex. For example, the deformation of the skin near a joint of a skeleton is mainly influenced by the position and orientation of the two (rigid) bones meeting in the joint. Thus, the positions and orientations of the two bones define two affine transformations. Different points on the skin are influenced differently by the two bones: points at the joint might be influenced equally by the two bones while points farther from the joint around one bone are more strongly influenced by that bone than the other. These different strengths of the influence of the two bones can be implemented by using different weights in the weighted average of the two transformations.

For the purpose of this tutorial, we use two uniform transformations  and , which are specified by the user. To this end a small JavaScript (which should be attached to the mesh that should be deformed, e.g. the default sphere) allows us to specify two other game objects and copies their model transformations to the uniforms of the shader:

In C#, the script (named "MyClass") would look like this: The two other game objects could be anything — I like cubes with one of the built-in semitransparent shaders such that their position and orientation is visible but they don't occlude the deformed mesh.

In this tutorial, the weight for the blending with the transformation  is set to  :

and the other weight is. Thus, the part with positive  coordinates is influenced more by   and the other part is influenced more by. In general, the weights are application dependent and the user should be allowed to specify weights for each vertex.

The application of the two transformations and the weighted average can be written this way:

Then the blended vertex has to be multiplied with the view matrix and the projection matrix. The product of these two matrices is available as :

In order to illustrate the different weights, we visualize  by the red component and   by the green component of a color (which is set in the fragment shader): For an actual application, we could also transform the normal vector by the two corresponding transposed inverse model transformations and perform per-pixel lighting in the fragment shader.

Complete Shader Code
All in all, the shader code looks like this: This is, of course, only an illustration of the concept but it can already be used for some interesting nonlinear deformations such as twists around the $$z$$ axis.

For skinned meshes in skeletal animation, many more bones (i.e. model transformations) are necessary and each vertex has to specify which bone (using, for example, an index) contributes with which weight to the weighted average. However, Unity computes the blending of vertices in software; thus, this topic is less relevant for Unity programmers.

Summary
Congratulations, you have reached the end of another tutorial. We have seen:
 * How to blend vertices that are transformed by two model matrices.
 * How this technique can be used for nonlinear transformations and skinned meshes.