12.4 - GLSL Operators (Mathematical and Logical)¶
GLSL is designed for efficient vector and matrix processing. Therefore almost all of its operators are overloaded to perform standard vector and matrix operations as defined in linear algebra. In cases where an operation is not defined in linear algebra, the operation is typically done component-wise, where the operation is performed on each individual element of the vector or matrix.
Almost all math operators work on both float and int data types, but not in the same expression. GLSL does not perform any automatic casting of data types. Therefore, make sure all of the operands in an expression are of the same data type. Here are some examples of invalid mixed mode expressions:
float a = 3 * 0.7; // Error. The 3 is an integer. Make it 3.0
int b = 10.0 * 0.7; // Error. You can't assign a float to an integer.
b = int(10.0 * 0.7); // Valid
vec3 c = vec3(1.0, 2.0, 3.0);
ivec3 d = ivec3(1,2,3);
vec3 e = c + d; // Error. You can't add floats and integers.
Vector algebra operations require that the operands be of the same size. For example, you can add two vec3‘s together, but not a vec3 and a vec4. The result of a vector operation is always the same size as the original operands (except in the cases where a scalar and a vector are used.)
GLSL only supports square matrices, so the size of two matrices must be equal to multiply them together. A vector is treated as either a row or column vector whenever it is multiplied by a matrix, whichever makes the operation correct. You do not have to transpose a vector as you would in normal matrix algebra.
The GLSL compiler optimizes your code for execution. Therefore, don’t make overly complex equations and think you are somehow making the code faster. A series of well documented equations is preferable over a single, hard to understand, equation.
GLSL Operators¶
The table below lists the GLSL operators in precedence order and shows the type of overloaded operations they can perform. The examples use the following variables. The term “scalar” means “non-vector” or “single value”.
bool b; // scalar
int i; // scalar
float f; // scalar
bvec2 bv; // Or bvec3, bvec4 (Boolean vector)
ivec2 iv; // Or ivec3, ivec4 (integer vector)
vec2 v; // Or vec3, vec4 (floating point vector)
mat2 m; // Or mat3, mat4 (floating point matrix)
# | OP | Description | Examples | Type of operation |
---|---|---|---|---|
1 | ( ) | grouping | ( ) | |
2 | [ ]
( )
.
++
- -
|
array subscript
function call
field selector, swizzle
postfix increment
postfix decrement
|
v[2]
func( )
v.xyz
i++
f++
iv++
v++
m++
|
scalar
scalar
component-wise
component-wise
component-wise
|
3 | ++
- -
+
-
!
|
prefix increment
prefix decrement
unary + (positive value)
unary - (negative value)
Boolean negation
|
++i
++f
++iv
++v
++m
-i
-f
-iv
-v
-m
!b
|
scalar
scalar
component-wise
component-wise
component-wise
scalar
scalar
component-wise
component-wise
component-wise
bool
|
4 | multiply
division
|
i * i
f * f
v * v
iv * iv
i * iv
f * v
f * m
v * m
m * v
m * m
i / i
f / f
v / v
iv / iv
iv / i
v / f
m / f
|
scalar
scalar
component-wise
component-wise
component-wise
component-wise
component-wise
linear algebra
linear algebra
linear algebra
scalar
scalar
component-wise
component-wise
component-wise
component-wise
component-wise
|
|
5 | +
-
|
addition
subtraction
|
i + i
f + f
iv + iv
v + v
m + m
|
scalar
scalar
component-wise
component-wise
component-wise
|
7 | <
>
<=
>=
|
less than
greater than
less than or equal to
greater than or equal to
|
i < i
f < f
|
bool
bool
|
8 | ==
!=
|
equality
not equality
|
i == i
f == f
bv == bv
iv == iv
v == v
m == m
|
bool
bool
bool
bool
bool
bool
|
12 | &&
|
logical AND
|
b && b
|
bool
|
13 | ^^
|
logical EXCLUSIVE OR
|
b ^^ b
|
bool
|
14 | ||
|
logical INCLUSIVE OR
|
b || b
|
bool
|
15 | ?:
|
selection
|
b ? n : m
|
returns n if b
|
16 | assignment
addition assignment
subtraction assignment
multiplication assignment
division assignment
|
bool
scalar
scalar
vector
vector
vector
matrix
scalar
scalar
component-wise
component-wise
component-wise
scalar
scalar
component-wise
component-wise
component-wise
component-wise
component-wise
scalar
scalar
component-wise
component-wise
component-wise
component-wise
component-wise
|
||
17 | ,
|
sequence
|
Notice that the precedence values in the left column of the above table are not sequential. This is because the designers of GLSL have reserved some operators for future versions. The reserved operators are:
# | OP | Description | Examples | Type of operation |
---|---|---|---|---|
4 | %
|
modulus (reserved)
|
(not implemented)
|
|
6 | <<
>>
|
bitwise shift (reserved)
bitwise shift (reserved)
|
(not implemented)
(not implemented)
|
|
9 | &
|
bit-wise AND (reserved)
|
(not implemented)
|
|
10 | ^
|
bit-wise EXCLUSIVE OR
|
(not implemented)
|
|
11 | bit-wise INCLUSIVE OR
|
(not implemented)
|