What Does the Precise Qualifier Do in GLSL?

The precise qualifier in the OpenGL Shading Language (GLSL) ensures exact reproducibility of floating-point calculations across different shaders or stages of a graphics pipeline. Modern GPU shader compilers aggressively optimize math operations through reordering, algebraic simplification, and hardware-specific instruction fusion like Fused Multiply-Add (FMA). While these optimizations increase execution speed, they introduce tiny rounding discrepancies that cause rendering artifacts such as visual seams, cracking between tessellated geometry, or Z-fighting. Declaring a variable, function return value, or computation with precise forces the compiler to disable unsafe optimizations and evaluate the expression in strict evaluation order, guaranteeing bit-exact consistency.

The Problem: Compiler Optimizations and Invariance Issues

GPU architectures prioritize throughput and parallel execution. To achieve high performance, GLSL compilers routinely perform optimizations on floating-point expressions:

In graphics rendering, identical math must often produce identical outputs. For instance, when adjacent polygons share vertices computed in different shader stages or draw calls, slight floating-point divergences cause the vertices to separate, creating visible cracks or flickering geometry.

How the Precise Qualifier Works

The precise keyword acts as a compiler constraint. It alters code generation rules for any calculation contributing to the declared variable:

precise vec4 position;
position = mvpMatrix * vertex;

When a variable is marked precise, the compiler must adhere to strict behavioral rules:

  1. Strict Evaluation Order: Operations must follow standard operator precedence and grouping parentheses exactly as written in the source code.
  2. Prevention of Unsafe Algebraic Reductions: The compiler is forbidden from restructuring expressions using distributive, associative, or commutative identities that could alter precision.
  3. Consistent FMA Usage: The compiler must either avoid fusing operations arbitrarily or ensure operations fuse identically everywhere the precise value is evaluated.

Decorating Functions and Return Values

The precise qualifier can also be applied to function declarations to ensure that all internal computations producing the return value maintain precision:

precise float calculateDepth(float near, float far, float z) {
    return (far + near) / (far - z);
}

precise vs. The invariant Qualifier

GLSL provides two primary qualifiers for consistency: invariant and precise. While they address similar problems, they operate at different scopes:

Performance Considerations

Restricting compiler optimizations prevents the GPU driver from scheduling instructions in the most latency-tolerant or parallel manner. Overusing the precise qualifier across an entire shader can lead to measurable frame rate drops due to higher register pressure and lost FMA optimization opportunities.

To maintain optimal rendering performance, the precise qualifier should be restricted strictly to critical calculations where geometric continuity and bit-level invariance are necessary, such as shared screen-space coordinates, displacement mapping calculations, tessellation evaluation shaders, and shadow-map depth matching.