# GLSL Programming/Vector and Matrix Operations

The syntax of GLSL is very similar to C (and therefore to C++ and Java); however, there are built-in data types and functions for floating-point vectors and matrices, which are specific to GLSL. These are discussed here. A full description of GLSL can be found in the literature in the “Further Reading” section.

### Data Types

In GLSL, the types vec2, vec3, and vec4 represent 2D, 3D, and 4D floating-point vectors. (There are also types for integer and boolean vectors, which are not discussed here.) Vector variables are defined as you would expect if C, C++ or Java had these types:
The data types for floating-point 2×2, 3×3, and 4×4 matrices are: mat2, mat3, and mat4:

### Precision Qualifiers

When declaring a floating-point variable (including vector and matrix variables), you can suggest a precision by using one of the precision qualifiers lowp, mediump, or highp, for example:
The idea is that lowp variables require less computation time and less storage (and therefore also less bandwidth) than mediump variables, and mediump variables require less time than highp variables. Thus, for best performance you should use the lowest precision that still gives satisfactory results. (There are only a few exceptions to this, for example accessing individual elements of a lowp vector can be slower than for a mediump vector because it requires additional decoding.)
Note that it is up to the compiler and driver to decide which precision is actually used; the precision qualifiers are only suggestions by the programmer. Also note that the range of lowp variables can be very limited (e.g. from -2.0 to 2.0), thus, lowp is most useful for colors but usually not for positions.
To define default precisions for all floating-point variables, you should use the precision command, for example:
This will use mediump if no explicit precision qualifier is specified for a floating-point variable. Without the command, the default precision for float is highp in an OpenGL or OpenGL ES vertex shader, highp in an OpenGL fragment shader, and undefined in an OpenGL ES fragment shader. (In Unity, however, the precision command is not available and the default precision is highp in a vertex shader and mediump in a fragment shader.)

### Constructors

Vectors can be initialized and converted by constructors of the same name as the data type:
Note that some GLSL compilers will complain if integers are used to initialize floating-point vectors; thus, it is good practice to always include the decimal point.
One can also use one floating-point number in the constructor to set all components to the same value:
Casting a higher-dimensional vector to a lower-dimensional vector is also achieved with these constructors:
Casting a lower-dimensional vector to a higher-dimensional vector is achieved by supplying these constructors with the correct number of components:
Similarly, matrices can be initialized and constructed. Note that the values specified in a matrix constructor are consumed to fill the first column, then the second column, etc.:
If a larger matrix is constructed from a smaller matrix, the additional rows and columns are set to the values they would have in an identity matrix:
If a smaller matrix is constructed from a larger matrix, the top, left submatrix of the larger matrix is chosen, e.g. in the last line of the previous example.

### Components

Components of vectors are accessed by array indexing with the-operator (indexing starts with 0) or with the .-operator and the element names x, y, z, w or r, g, b, a or s, t, p, q:
It is also possible to construct new vectors by extending the .-notation ("swizzling"):
Matrices are considered to consist of column vectors, which are accessed by array indexing with the-operator. Elements of the resulting (column) vector can be accessed as discussed above:

### Operators

If the binary operators *, /, +, -, =, *=, /=, +=, -= are used between vectors of the same type, they just work component-wise:
Note in particular that a * b represents a component-wise product of two vectors, which is not often seen in linear algebra.
For matrices, these operators also work component-wise, except for the *-operator, which represents a matrix-matrix product, e.g.:
$\mathrm {A} \mathrm {B} =\left[{\begin{matrix}a_{1,1}&a_{1,2}\\a_{2,1}&a_{2,2}\end{matrix}}\right]\left[{\begin{matrix}b_{1,1}&b_{1,2}\\b_{2,1}&b_{2,2}\end{matrix}}\right]$  $=\left[{\begin{matrix}a_{1,1}b_{1,1}+a_{1,2}b_{2,1}&a_{1,1}b_{1,2}+a_{1,2}b_{2,2}\\a_{2,1}b_{1,1}+a_{2,2}b_{2,1}&a_{2,1}b_{1,2}+a_{2,2}b_{2,2}\end{matrix}}\right]$
And in GLSL:
For a component-wise matrix product, the built-in function matrixCompMult is provided.
The *-operator can also be used to multiply a floating-point value (i.e. a scalar) to all components of a vector or matrix (from left or right):
Furthermore, the *-operator can be used for matrix-vector products of the corresponding dimension, e.g.:
$\mathrm {M} \mathbf {v} =\left[{\begin{matrix}m_{1,1}&m_{1,2}\\m_{2,1}&m_{2,2}\end{matrix}}\right]\left[{\begin{matrix}v_{1}\\v_{2}\end{matrix}}\right]$  $=\left[{\begin{matrix}m_{1,1}v_{1}+m_{1,2}v_{2}\\m_{2,1}v_{1}+m_{2,2}v_{2}\end{matrix}}\right]$
And in GLSL:
Note that the vector has to be multiplied to the matrix from the right.
If a vector is multiplied to a matrix from the left, the result corresponds to multiplying a row vector from the left to the matrix. This corresponds to multiplying a column vector to the transposed matrix from the right:
$\mathbf {v} ^{T}\mathrm {M} =\left(\mathrm {M} ^{T}\mathbf {v} \right)^{T}$
In components:
$\mathbf {v} ^{T}\mathrm {M} =\left[{\begin{matrix}v_{1}&v_{2}\end{matrix}}\right]\left[{\begin{matrix}m_{1,1}&m_{1,2}\\m_{2,1}&m_{2,2}\end{matrix}}\right]$  $=\left[{\begin{matrix}v_{1}m_{1,1}+v_{2}m_{2,1}&v_{1}m_{1,2}+v_{2}m_{2,2}\end{matrix}}\right]$  $=\left(\left[{\begin{matrix}m_{1,1}&m_{2,1}\\m_{1,2}&m_{2,2}\end{matrix}}\right]\left[{\begin{matrix}v_{1}\\v_{2}\end{matrix}}\right]\right)^{T}$  $=\left(\mathrm {M} ^{T}\mathbf {v} \right)^{T}$
Thus, multiplying a vector from the left to a matrix corresponds to multiplying it from the right to the transposed matrix:
Since there is no built-in function to compute a transposed matrix, this technique is extremely useful: whenever a vector should be multiplied with a transposed matrix, one can just multiply it from the left to the original matrix. Several applications of this technique are described in Section “Applying Matrix Transformations”.

### Built-In Vector and Matrix Functions
#### Component-Wise Functions

As mentioned, the function
computes a component-wise product for the matrix types mat2, mat3 and mat4, which are denoted as TYPE.
The following functions work component-wise for variables of type float, vec2, vec3 and vec4, which are denoted as TYPE:
There are more built-in functions, which also work component-wise but are less useful for vectors, e.g., abs, sign, floor, ceil, fract, mod, step, smoothstep, sqrt, inversesqrt, pow, exp, exp2, log, log2, radians (converts degrees to radians), degrees (converts radians to degrees), sin, cos, tan, asin, acos, atan (with one argument and with two arguments for signed numerator and signed denominator), lessThan, lessThanEqual, greaterThan, greaterThanEqual, equal, notEqual, and not.

#### Geometric Functions

The following functions are particular useful for vector operations. TYPE is any of: float, vec2, vec3 and vec4 (only one of them per line).

#### Functions for Physics

The function
computes the direction of a refracted ray if i specifies the normalized(!) direction of the incoming ray and n specifies the normalized(!) normal vector of the interface of two optical media (e.g. air and water). The vector n should point to the side from where i is coming, i.e. the dot product of n and i should be negative. The floating-point number r is the ratio of the refractive index of the medium from where the ray comes to the refractive index of the medium on the other side of the surface. Thus, if a ray comes from air (refractive index about 1.0) and hits the surface of water (refractive index 1.33), then the ratio r is 1.0 / 1.33 = 0.75. The computation of the function is:
As the code shows, the function returns a vector of length 0 in the case of total internal reflection (see the entry in Wikipedia), i.e. if the ray does not pass the interface between the two materials.

### Further Reading

All details of GLSL for OpenGL are specified in the “OpenGL Shading Language 4.10.6 Specification” available at the Khronos OpenGL web site.
More accessible descriptions of the OpenGL shading language for OpenGL are given in recent editions of many books about OpenGL, e.g. in Chapter 15 of the “OpenGL Programming Guide: The Official Guide to Learning OpenGL, Versions 3.0 and 3.1” (7th ed.) by Dave Shreiner published 2009 by Addison-Wesley.
All details of GLSL for OpenGL ES 2.0 are specified in the “OpenGL ES Shading Language 1.0.17 Specification” available at the “Khronos OpenGL ES API Registry”.
A more accessible description of the OpenGL ES shading language is given in Chapter 5 and Appendix B of the book “OpenGL ES 2.0 Programming Guide” by Aaftab Munshi, Dan Ginsburg and Dave Shreiner published by Addison-Wesley (see its web site).
< GLSL Programming