What Does the dot Function Compute in GLSL?

The dot function in OpenGL Shading Language (GLSL) calculates the mathematical dot product—also known as the scalar product—between two vectors of identical dimensions. In real-time computer graphics, this operation is one of the most fundamental vector computations, serving as the backbone for calculating lighting angles, surface orientations, projections, and shading falloffs.

Mathematical Definition

The dot product of two vectors \(\mathbf{a}\) and \(\mathbf{b}\) multiplies corresponding components and sums the results. For an \(n\)-dimensional vector:

\[\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i\]

For a 3D vector (vec3), the calculation in GLSL evaluates as:

\[\mathbf{a} \cdot \mathbf{b} = a_x b_x + a_y b_y + a_z b_z\]

The geometric definition relates the dot product to the lengths of both vectors and the cosine of the angle \(\theta\) between them:

\[\mathbf{a} \cdot \mathbf{b} = \Vert{}\mathbf{a}\Vert{} \Vert{}\mathbf{b}\Vert{} \cos\theta\]

When both input vectors are normalized to unit length (\(\Vert{}\mathbf{a}\Vert{} = 1\) and \(\Vert{}\mathbf{b}\Vert{} = 1\)), the formula simplifies directly to:

\[\mathbf{a} \cdot \mathbf{b} = \cos\theta\]

GLSL Syntax and Supported Types

The dot function accepts floating-point vectors (vec2, vec3, vec4) as well as double-precision floating-point vectors (dvec2, dvec3, dvec4). Both arguments must have the exact same type and dimension, and the function returns a single scalar value (float or double).

// Example vector declarations
vec3 normal = normalize(vNormal);
vec3 lightDir = normalize(uLightPosition - vPosition);

// Compute scalar dot product
float NdotL = dot(normal, lightDir);

Interpreting the Output

When evaluating normalized vectors, the return value of dot(a, b) falls strictly within the range \([-1.0, 1.0]\):

Common Use Cases in Shaders

1. Lambertian Diffuse Lighting

Diffuse illumination relies on Lambert's cosine law, where surface brightness is proportional to the cosine of the angle between the surface normal \(\mathbf{N}\) and the incident light direction \(\mathbf{L}\). Because lighting cannot be negative, results are clamped to zero:

float diffuse = max(dot(normal, lightDirection), 0.0);

2. Specular Highlights

In the Blinn-Phong reflection model, specular reflection is determined by taking the dot product between the surface normal \(\mathbf{N}\) and the halfway vector \(\mathbf{H}\) between the view direction and light direction:

float specular = pow(max(dot(normal, halfVector), 0.0), shininess);

3. Vector Length and Distance

The squared length of a vector can be computed using a dot product with itself, which avoids an expensive square root operation when comparing relative distances:

float lengthSquared = dot(v, v);
float len = sqrt(dot(v, v)); // Equivalent to length(v)

4. Fresnel and Rim Lighting Effects

Rim lighting and Fresnel equations frequently evaluate the dot product between the surface normal and the view direction (\(\mathbf{N} \cdot \mathbf{V}\)) to detect glancing angles along polygon silhouettes.