What Preprocessor Directives Does GLSL Support?

The OpenGL Shading Language (GLSL) features a built-in preprocessor closely modeled on the standard C/C++ preprocessor, used to control compilation conditionally, define macros, enforce language versions, and manage hardware extensions. While it supports familiar operations like conditional branching and macro expansion, it includes GLSL-specific directives like #version and #extension, while omitting standard features like #include from the core specification.

Macro Definition and Undefinition

GLSL allows basic macro replacement and parameterized macros across shader code.

GLSL also provides standard predefined macros, such as __LINE__, __FILE__, __VERSION__, and GL_core_profile (or GL_es_profile), which allow shaders to adapt dynamically to their execution context.

Conditional Compilation

Conditional directives enable shaders to include or exclude blocks of code based on macro definitions or integer constant expressions.

Floating-point operations and typecasts are not permitted within GLSL preprocessor conditional expressions; only integer constant expressions and operators (such as arithmetic, bitwise, and logical operators) are valid.

Version Declaration: #version

The #version directive is mandatory for modern GLSL and informs the driver which specification version to use when parsing the shader.

For example, #version 330 core specifies version 3.30 using the core profile, whereas #version 300 es designates OpenGL ES 3.0.

Extension Handling: #extension

The #extension directive controls compiler behavior regarding optional or vendor-specific GLSL capabilities.

Diagnostic and Line Control Directives

GLSL includes directives to adjust compiler error tracking and report custom compilation errors.

Compiler Pragma Controls: #pragma

The #pragma directive passes implementation-specific instructions to the shader compiler. Standard GLSL specifications define several reserved pragmas:

Omitted Directives

The core GLSL specification does not include a standard #include directive. Shader file composition, module management, and header inclusions must either be resolved on the CPU before passing the shader string to glShaderSource, or handled using specialized extensions like GL_ARB_shading_language_include or GL_GOOGLE_include_directive where driver and runtime support exist.