What Is the GLSL Reflect Function Formula?

In computer graphics and shader programming, the GLSL reflect function calculates the reflection direction for an incident vector against a given surface normal. This article breaks down the mathematical formula behind reflect(I, N), provides the step-by-step vector derivation, highlights the critical direction requirements for input vectors, and explains how this operation powers classic specular illumination models like the Phong reflection model.

The Mathematical Definition

The built-in GLSL function signature is defined as:

genType reflect(genType I, genType N);

According to the OpenGL Shading Language specification, the exact formula evaluated by this function is:

\[R = I - 2.0 \cdot (N \cdot I) \cdot N\]

Where:

Derivation of the Reflection Formula

To understand why this formula works geometrically, consider an incident ray \(I\) hitting a planar surface with normal \(N\):

  1. Decomposing the Incident Vector: Any vector \(I\) can be decomposed into two orthogonal components: a component parallel to the normal (\(I_{\parallel}\)) and a component perpendicular to the normal (\(I_{\perp}\)):

\[I = I_{\parallel} + I_{\perp}\]

  1. Calculating the Parallel Component: The projection of \(I\) onto the unit normal vector \(N\) gives the parallel component:

\[I_{\parallel} = (I \cdot N) N\]

  1. Calculating the Perpendicular Component: Subtracting the parallel component from \(I\) yields the perpendicular component:

\[I_{\perp} = I - I_{\parallel} = I - (I \cdot N) N\]

  1. Inverting Across the Surface: Upon ideal specular reflection, the component parallel to the surface tangent (\(I_{\perp}\)) preserves its direction and magnitude, while the component perpendicular to the surface (\(I_{\parallel}\)) reverses direction:

\[R = I_{\perp} - I_{\parallel}\]

  1. Combining Terms: Substituting the definitions of \(I_{\perp}\) and \(I_{\parallel}\) into the reflection expression yields:

\[R = (I - (I \cdot N) N) - (I \cdot N) N\]

\[R = I - 2.0 \cdot (I \cdot N) N\]

Because the dot product is commutative (\(I \cdot N = N \cdot I\)), this matches the standard GLSL implementation.

Critical Implementation Details

When working with reflect in shaders, two key requirements ensure accurate visual results:

Application in Phong Lighting

In the classic Phong reflection model, the specular highlight depends on the alignment between the reflected light vector \(R\) and the viewing vector \(V\):

// Calculate incident light vector from light to fragment
vec3 lightDir = normalize(fragPos - lightPos);
vec3 normal = normalize(vNormal);

// Compute reflection vector
vec3 reflectDir = reflect(lightDir, normal);

// Specular contribution
vec3 viewDir = normalize(cameraPos - fragPos);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);

By computing \(R\) directly through optimized hardware instructions, reflect delivers fast specular highlights, environment map lookups, and ray tracing calculations in modern rendering pipelines.