Course notes for November 27

(more detail and diagrams coming soon)

Perspective interpolation:

What Graphics Processing Units (GPUs) are actually doing when they "linearly interpolate" the from output values of vertex shaders, to create the input values for fragment shaders, is not simply linear interpolation. Rather, it is perspective linear transformation.

Linear transformation between two values u0 and u1 by fraction t is very simple:

lerp(t , u0 , u1) = (1-t) u0 + t u1

But this doesn't work when objects are at different distances in the presence of perspective. For any parameter u at distance z, the perspective transformation is, essentially:

u → u/z
z → 1/z

So in order to do a proper linear transformation between value u0 at distance z0 and u1 at distance z1, we need to do:

lerp(t , u0/z0 , u1/z1) / lerp(t , 1/z0 , 1/z1)

Local surface mesh refinement:

In class we talked about two different approaches to local refinement of polygon meshes:

Local refinement by subdivision:

To locally add detail to just one part of a triangular mesh, we can convert a single triangle to four smaller triangles, by adding a vertex to the midpoint of each of the triangle's three edges.

To avoid creating cracks in the mesh, we need to split each of the three adjoining triangles into two triangles. This doesn't work well if our original triangle is continually subdivided. So we need to "spread out" the detail amongst adjoining triangles in the mesh, as I showed in class. I will add those details to these course notes shortly.

Refinement by deleting shortest edge, dividing longest edge:

Another approach is to define some metric for edge length (which doesn't need to be the literal edge length), and then iteratively remove the smallest edge from the mesh while splitting the longest edge. Deleting the smallest edge removes two triangles and one vertex, whereas splitting the longest edge adds two triangles and one vertex.

To make this run reasonably fast, you should use a binary min heap and max heap to keep track of the current shortest and longest edges.

By choosing interesting "edge length" metrics, you can create more detail in some parts of the mesh, while removing detail from other parts. I wil be adding detail on this topic to the course notes over the next few days.

spring/mass dynamics:

Double integral

The simplest form of dynamics is a double integral of force (which is mass times accelaration), to get position. This integral can be modified by a damping factor (to model frictional forces on the spring) and mass. The code for the behavior of a spring object, whose update() function should be called on every animation frame, is essentially as follows:

    function getPosition() { return P; }
    function setDamping(t) { damp = t; }
    function setForce  (t) { F = t; }
    function setMass   (t) { mass = Math.max(0.001, t); }
    function update(elapsed) {
       V += (F -  P) / mass * elapsed;
       P = (P + V) * (1 - damp * elapsed);
    var P = 0, V = 0, F = 0, mass = 1.0, damp = 1.0;

On-line examples:

Springs connecting each pair of atoms

The key to implementing something like the molecules example above (and the springy guy as well) is that for every pair of atoms that are not connected by a molecular bond, we place an invisible spring, which is continually trying to maintain its original length. Any any graph with n nodes there are n(n-1)/2 possible edges, so for a model with A atoms and L links, we need A(A-1)/2 - L springs.

Chrome mapping:

The image to the right was created when Gene Miller, one of my collaborator's at MAGI, went out to the company parking lot and took a photo of a Christmas tree ornament. We then scanned the resulting photograph, and used the result (after tone mapping, because the sun was very bright) as an environment map for my implicit surface modeler.

A more standard way to create an environment map is to take six very wide angle images of a computer graphic scene. Each of these images is then used as one face of an "environment map" cube.

Then within a fragment shader, after a reflection vector R = (x,y,z) has been computed, we do the following operation:

  1. Figure out which of the following: -x,-y,-z,x,y,z is largest.

    This will tell us which of the six cubic faces to look-up into.

  2. Divide the other two coordinates by this value, and use the result to do a texture look-up into that face of the environment cube.

    For example, if z is the largest of those six values, then the (u,v) texture parameters are: u = (1 + x/z) / 2 , v = (1 + y/z) / 2.

Collision avoidance:

When trying to figure out whether two objects intersect (say, for doing physics or character animation), it can be very expensive to run through all of the triangles of two objects, since the number of pair-wise comparisons needed goes up as the square of the number of triangles involves.

For this reason, we often do simplified approximations using simple shapes that are roughly correspond to the model shape. Two common shapes used for this purpose are spheres and cylinders.

To see whether two spheres intersect, we just need to do the following:

  • Let S0 be a sphere at center C0 and radius R0.

  • Let S1 be a sphere at center C1 and radius R1.

  • The two spheres intersect if: |C1 - C0| < R0 + R1.
It's faster to use the square of the distance between the two sphere centers, which requires no square root:
  • D = C1 - C0
  • Spheres intersect iff:   DD < (R0 + R1)2

Rather than using spheres, you can also use cylinders. It's trade-off, since the computation between two cylinders is slower, but for things like character body limbs you need fewer cylinders than spheres for a good shape approximation.

The key to seeing whether two cylinders intersect is to compute the points where their center axes approach each other most closely, and then compute the separation between those two points exactly as you would for two spheres.

Graphics in the fourth dimension:

We ended the lecture with a discussion of graphics in the fourth dimension, touching on such topics as the hypercube, the four dimensional simplex, a 4D virtual trackball, shading, perspective, and a very brief discussion of my favorite shape, the 24 cell (the close packing formation of hyperspheres).

In the coming days I will add to the notes on this topic, for those of you who want to do a project in four dimensions, or are just interested in the topic.


Some time during the next week, please email me a proposal for an individual final project. Your project will be due by Friday, December 20.

After you email me, I may not get back to you right away, because it make take some thinking to give you the best advice, so please try to be patient.