Shader Preprocessor

The shader preprocessor is an optional step before shader compilation of text shaders in Godot. If you don't need it, you may ignore it, but it contains some useful macros which may speed up your productivity.

#define

Syntax: #define identifier <replacement_code>.

Defines the identifier after that directive as a macro, and replaces all successive occurrence of it with the replacement code given in the shader. If the replacement code is not defined, it may only be used within #ifdef or #ifndef directives.

shader_type spatial;

#define USE_MY_COLOR
#define MY_COLOR vec3(1, 0, 0)

void fragment() {
#ifdef USE_MY_COLOR
    ALBEDO = MY_COLOR;
#endif
}

#if

Syntax: #if condition.

The #if directive checks the condition and if it evaluates to a non-zero value, the code block is included, otherwise it is skipped. In order to evaluate, the condition must be an expression giving a simple floating-point, integer or boolean result. There may be multiple condition blocks connected by || or && operators. It may be continued by a #else block, but must be ended with the #endif directive.

#define VAR 3
#define USE_LIGHT 0 // evaluates to false
#define USE_COLOR 1 // evaluates to true

#if VAR == 3 && (USE_LIGHT || USE_COLOR)


#endif

#ifdef

Syntax: #ifdef identifier.

Checks whether the passed identifier is defined by #define before that directive. Useful for creating multiple shader versions in the same file. It may be continued by a #else block, but must be ended with the #endif directive.

#define USE_LIGHT
#ifdef USE_LIGHT

#endif

#ifndef

Syntax: #ifndef identifier.

Similar to #ifdef but checks whether the passed identifier is not defined by #define before that directive.

#else

Syntax: #else.

Defines the optional block which is included when the previously defined #if, #ifdef or #ifndef directive evaluates to false.

shader_type spatial;

#define MY_COLOR vec3(1, 0, 0)

void fragment() {
#ifndef MY_COLOR
    ALBEDO = MY_COLOR;
#else
    ALBEDO = vec3(0, 0, 1);
#endif
}

#endif

Syntax: #endif.

Used as terminator for the #if, #ifdef, #ifndef or subsequent #else directives.

#undef

Syntax: #undef identifier.

The #undef directive may be used to cancel the previously defined #define directive:

#define MY_COLOR vec3(1, 0, 0)

vec3 get_red_color() {
    return MY_COLOR;
}

#undef MY_COLOR
#define MY_COLOR vec3(0, 1, 0)

vec3 get_green_color() {
    return MY_COLOR;
}

Without #undef in that case there will be a macro redefinition error.

#include

Syntax: #include "path".

The #include directive includes the content of shader include to a shader. It may be used in any place, but is recommended at the beginning of the shader file, after the shader_type to prevent possible errors. The shader include may be created by using a File → Create Shader Include menu option of the shader editor.

#include "my_shader_inc.gdshaderinc"

#pragma

Syntax: #pragma value.

The #pragma directive provides additional information to the preprocessor or compiler.

Currently, it may have only one value: disable_preprocessor. If you don't need the preprocessor, use that directive, and it will speed up the shader compilation by excluding the preprocessor step.

#pragma disable_preprocessor