CS424 Notes, 22 February 2012
- Generated Texture Coordinates.
- If texture coordinates are not provided as part of a model, it might still be possible to apply a texture to the model using generated texture coordinates. One very simple idea would be to use the x and y object coordinates of a vertex as texture coordinates for that vertex. However, that does not work very well in general.
- Another option is cube mapping. The object
coordinates of a vertex have three components, x,
y, and z. Cube mapping uses two of the three
coordinates, and it decides which two to use based on
the general direction that the primitive is facing.
This can be checked by looking at the components of
the normal vector. The algorithm is something like:
let (x,y,z) be the object coordinates let (dx,dy,dz) be the normal vector if abs(dx) is larger than abs(y) and abs(z): if dx > 0 use (y,z) as the texture coordinates else use (z,y) as the texture coordinates else if abs(dy) is larger than abs(dx) and abs(dz) if (dy > 0) use (z,x) as the texture coordinates else use (x,z) as the texture coordinates else if (dz > 0) use (x,y) as the texture coordinates else use (y,x) as the texture coordinates
- Other types of mapping are possible. "Tube mapping," for
example might, I think, compute the texture coordinates (s,t)
from the object coordinates (x,y,z) as:
t = y s = atan(x,z) / (2.0*pi)In this case, the "tube" wraps around the y-axis. Furthermore, instead of object coordinates, you might use world coordinates or even window coordinates.
- Affine Transformations in 3D
- 3D has the same type of affine transforms as 2D: scaling, rotation, translation, and shear (although as in 2D, shear is not as important).
- Translation in 3D is similar to 2D, but now there are three coordinate directions. So a translation is given by three numbers (dx,dy,dz), giving the amount of motion in the x, y, and z directions. A value of 0 means no translation in that direction.
- Scaling also uses three numbers, (sx,sy,sz), to give the scaling factors in the x, y, and z directions. For uniform scaling, all three numbers are the same. A value of 1 means no scaling in that direction. A negative scaling factor implies a reflection. A scaling factor of 0 is bad, since it collapses an entire direction down to a single point. For example, scaling by (1,1,0) would map every point to a point in the xy-plane.
- Rotation introduces a new wrinkle: In 3D, you don't rotate about a point. Instead, you rotate around a line, which is called the axis of rotation. For example, the Earth rotates about a line that runs through the Earth's north and south pole. Ordinarily, the axis for a 3D rotation goes through the origin. (If you want an axis that goes through a different point, you can translate that point to the origin, rotate about a line through the origin, then translate back.)
- Suppose that you want to rotate about the line that goes through (0,0,0) and (a,b,c). There is still the question of which direction do you rotate for a positive angle? In 3D, you can't just say "clockwise" or "counterclockwise." The answer is given by the right-hand rule: Point your thumb in the direction from (0,0,0) to (a,b,c), and your fingers will curl in the direction of rotation for a positive rotation.
- Rotations about the x-axis, about the y-axis, and about the z-axis are common, but rotations about other axes are also useful.
- Matrices for 3D
- Equations for an affine transform applied to (x,y,z) have
xnew = a * xold + d * xold + g * xold + j; xnew = b * xold + e * xold + h * xold + k; xnew = c * xold + f * xold + i * xold + m;where all coefficients are constants.
- Just as an affine transform in 2D can be expressed as a 3-by-3 matrix, an affine transform in 3D can be expressed as a 4-by-4 matrix. The bottom row of the matrix is (0,0,0,1). To transform (x,y,z), multiply (x,y,z,1) by the matrix, and discard the final coordinate to get the new (x,y,z).
- Equations for an affine transform applied to (x,y,z) have the form
- gl-matrix.js defines three "objects" vec3, mat3, and mat4 but they are not objects in the sense of object oriented programming. In Java, they would just be classes that contain a bunch of static methods, like the Math class. For example, mat4 is a collection of functions for operating on 4-by-4 matrices, where each matrix is implement as an array of 16 numbers. For example, mat4.translate(matrix,[2,3,-1]) modifies matrix by multiplying it on the right by a translation, where the vector [2,3,-1] gives the translation amounts in the x, y, and z directions. In particular, note that mat4 is not a matrix! The matrix that is being operated on is passed as the first parameter to the function.
- Here is an example of using mat4 to make a transformation
matrix representing a scale, followed by a rotation, followed by
var modelView = mat4.create(); mat4.identity(modelView); // Set to identity mat4.translate(modelView, [0, 0, -10]); // Translate back 10 units mat4.rotate(modelView, Math.PI/2, [0, 1, 0]); // Rotate 90 degrees around the Y axis mat4.scale(modelView, [2, 2, 2]); // Scale by 200%This example is taken directly from the library's web site. Note that mat4.create() makes a new matrix. You could also create it with new Array(16), but mat4.create() makes a Float32Array, which is more efficient and better adapted to WebGL.
- What should we do about the stack of transformations that is needed to implement hierarchical graphics.