Transformation
You may need to read the article about uniforms before this one. Additionally, although it isn't necessary, it might be useful to have prior knowledge of linear algebra.
A transformation is a way to change something. There are three basic transformations: translation, rotation, and scaling.
Translation
A translation is performed by adding a vector value to each vertex. For an initial vector and a translation vector , the resulting vector is .
#version 300 es
in vec4 a_position;
uniform vec4 u_translation;
void main() {
gl_Position = a_position + u_translation;
}
Rotation
A rotation is performed by multiplying each vertex by a point on the unit circle. Given a rotation of radians, an equivalent point on the unit circle is . To rotate an initial vector by radians, use , where and .
#version 300 es
in vec4 a_position;
uniform float u_rotation;
void main() {
float s = sin(u_rotation);
float c = cos(u_rotation);
float x = a_position.x * s + a_position.y * c;
float y = a_position.y * s - a_position.x * c;
gl_Position = vec4(x, y, a_position.zw);
}
Notice that the above code uses a_position.zw
. This is equivalent to vec2(a_position.z, a_position.w)
. It is possible to use any dimensions of a vector in any order to make another vector, such as a_position.xyz
or a_position.xzx
. This is called swizzling.
Scaling
A scaling is performed by multiplying each vertex by a vector. For an initial vector and a scaling vector , the resulting vector is .
#version 300 es
in vec4 a_position;
uniform vec4 u_scaling;
void main() {
gl_Position = a_position * u_scaling;
}
Matrices
Using the techniques described above works fine until you want to combine multiple, at which point a different shader is needed for each permutation of transformations.
The standard approach to applying transformations is with transformation matrices, which are square matrices that represent transformations. By using transformation matrices, the transformations can be applied to the matrix in any order in JavaScript before being passed to the shader. To transform a vertex by a transformation matrix, simply multiply the matrix by the vertex.
#version 300 es
in vec4 a_position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * a_position;
}
Matrix multiplication is noncommutative. When two transformation matrices are multiplied to combine their transformations, the transformations of the multiplicand are applied before those of the multiplier. In order for two matrices to be multipliable, the multiplicand must be of size and the multiplier must be of size . Note that vectors are matrices with only one column (size ).
Matrices can be constructed in specific ways such that multiplying them by a vector is equivalent to one of the basic transformation algorithms outlined above.
It can be helpful to use a library such as μMath for linear algebra.
Matrix Translation
Although translation is not a linear transformation, it is an affine transformation, so it can still be represented with matrices through the use of homogeneous coordinates. This is why it's necessary to use matrices and 4D vectors to represent 3D transformations.
The following matrix translates an initial vector by , resulting in a vector .
To see why this works, we can write out the steps of the matrix-vector multiplication, treating the fourth component of the vector as a 1 (since it is used to scale the entire vector).
Notice that this yields the same formula for translation from the beginning of this article. This can also be done with all of the following transformation matrices to see how they result in the proper transformation.
Matrix Rotation
The following matrix rotates an initial vector by radians around the axis, resulting in a vector , where and .
The following matrix rotates an initial vector by radians around the axis, resulting in a vector , where and .
The following matrix rotates an initial vector by radians around the axis, resulting in a vector , where and .
The following matrix rotates an initial vector by radians around the axis, resulting in a vector , where , , , and .
Matrix Scaling
The following matrix scales an initial vector by a scaling vector , resulting in a vector .
Orthographic Projection
A projection is a linear transformation from a vector space to itself. An orthographic projection is a projection that uses parallel lines to project its shape. A projection matrix is a transformation matrix that applies a projection.
An orthographic projection can be used to convert from screen space to clip space.
The following orthographic projection matrix converts a vector to a vector , where , , , , , and are the left, right, bottom, top, near, and far bounds of the view frustum, respectively.
The next article is about the scene graph.