Vector basics
vec2, vec3 and vec4, with swizzles, length, distance, normalize and cross.
How it works
GLSL thinks in vectors: UV coordinates A 2D position on a surface or the screen, usually from 0 to 1 on both axes. Shaders draw shapes and patterns as functions of it.vec2, vec3 and vec4 hold two, three or four floats. The same type stores a position, a
direction, a color or a UVA 2D position on a surface or the screen, usually from 0 to 1 on both axes. Shaders draw shapes and patterns as functions of it.uv = gl_FragCoord.xy / resolution
Building and combining
A constructor takes any mix of scalars and smaller vectors, as long as the component counts add up:
vec3 white = vec3(1.0); // one value fills every component
vec4 color = vec4(white * 0.5, 1.0); // a vec3 plus an alpha
vec2 a = vec2(1.0, 2.0);
vec2 b = a * 2.0 + vec2(0.5); // (2.5, 4.5)
vec2 c = a * b; // per component: (2.5, 9.0)
Dot product Multiplies two vectors component by component and adds the results. For unit vectors it is the cosine of the angle between them, from 1 (same direction) to -1 (opposite).a * b between two vectors multiplies component by component. It is neither the dot productMultiplies two vectors component by component and adds the results. For unit vectors it is the cosine of the angle between them, from 1 (same direction) to -1 (opposite).dot(a, b) = |a| |b| cos θvec2(1, 2) converts its arguments, but a * 2 is a compile error. Write 2.0.
Swizzles
Components are named Swizzle Reading or writing a vector's components by name, in any order, as in v.xy, color.bgr or p.yx. Repeats are allowed when reading.x y z w, r g b a or s t p q: the same four slots under three sets of names. Any
combination of names, in any order and with repeats, builds a new vector. This is a
swizzleReading or writing a vector's components by name, in any order, as in v.xy, color.bgr or p.yx. Repeats are allowed when reading.
vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
vec2 xy = v.xy; // (1, 2)
vec3 bgr = v.bgr; // (3, 2, 1)
vec2 yy = v.yy; // (2, 2)
v.zw = vec2(0.0); // writing works too, without repeats
One swizzle can’t mix sets: v.xg doesn’t compile.
Length, distance and normalize
length(v) is the vector’s magnitude: the square root of the sum of its squared components. distance(a, b) is
length(a - b), the space between two points. In a fragment shader, length(p) on a centered UV is the distance from
the center, the start of every circle and ring.
Normal A unit vector perpendicular to a surface, pointing the way it faces. Lighting and Fresnel effects compare it with other directions.normalize(v) divides a vector by its length, which keeps its direction and makes its length 1. Directions such as a
surface normalA unit vector perpendicular to a surface, pointing the way it faces. Lighting and Fresnel effects compare it with other directions.
Cross product
cross(a, b), defined for vec3 only, returns a vector perpendicular to both, whose length is |a| |b| sin θ. Its
direction follows the right-hand rule, so swapping the arguments flips it. Shaders use it to get a normal from two
edges of a triangle, or to complete a frame of three axes from two:
vec3 n = normalize(cross(edge1, edge2)); // perpendicular to the triangle
Further reading
- Euclidean vector (opens in a new tab)Reference
- length (opens in a new tab)Reference
- normalize (opens in a new tab)Reference