Version: 2023.2
Language : English
include and include_with_pragmas directives in HLSL
Targeting shader models and GPU features in HLSL

Provide information to the shader compiler in HLSL

In HLSL, you can use the following types of preprocessor directive to provide information to the shaderA program that runs on the GPU. More info
See in Glossary
compiler:

  • #pragma
  • #define_for_platform_compiler

Pragma directives

#pragma directives provide additional information to the shader compiler that isn’t covered by other types of preprocessor directive.

You can put #pragma directives anywhere in your HLSL code, but it is a common convention to put them at the start, like this:

#pragma target 3.0
#pragma exclude_renderers vulkan
#pragma vertex vert
#pragma fragment frag

// The rest of your HLSL code goes here

Limitations

There are some limitations around the use of #pragma directives:

  • You can use #pragmadirectives inside conditional (#if) directives if the expression depends only on:
    • Any custom #define directives in your own code
    • The following platform keywords: SHADER_API_MOBILE, SHADER_API_DESKTOP, UNITY_NO_RGBM, UNITY_USE_NATIVE_HDR, UNITY_FRAMEBUFFER_FETCH_AVAILABLE, UNITY_NO_CUBEMAP_ARRAY
    • The UNITY_VERSION macro
  • You can only use Unity-specific #pragma directives in .shader files, and in files that you include with the #include_with_pragmas directive. Unity does not support them in files that you include with the #include directive; the compiler ignores them.
  • You can only use standard HLSL #pragma directives in files that you include with the #include directive. Unity does not support them in .shader files, or in files that you include with an #include_with_pragmas directive; the compiler ignores them.

Note: If a shader file uses #include to import a file that contains an #include_with_pragmas directive, Unity ignores the #pragma directives in the file the #include_with_pragmas directive references.

Standard pragma directives

Unity supports all #pragma directives that are part of standard HLSL, as long as these directives are in regular include files. For more information on these directives, see the HLSL documentation: pragma Directive.

Surface Shaders

If you are writing a Surface ShaderA streamlined way of writing shaders for the Built-in Render Pipeline. More info
See in Glossary
, use this directive to tell the compiler which function to use as the surface function, and pass data to that function.

Statement Function
#pragma surface <surface function> <lighting model> <optional parameters> Compile the function with the given name as the surface shader, so that it works with the given lighting model. For more information, see Surface Shaders.

Shader stages

If you are writing a regular graphics shader, use these directives to tell the compiler which functions to use for different shader stages. The #pragma vertex and #pragma fragment directives are required, but other stages are optional.

Statement Function
#pragma vertex <name> Compile the function with the given name as the vertex shader. Replace <name> with the function name. This directive is required in regular graphics shaders.
#pragma fragment <name> Compile the function with the given name as the fragment shader. Replace <name> with the function name. This directive is required in regular graphics shaders.
#pragma geometry <name> Compile the function with the given name as the geometry shader. Replace <name> with the function name. This option automatically turns on #pragma require geometry; for more information, see Targeting shader models and GPU features in HLSL.

Note: Metal does not support geometry shaders.
#pragma hull <name> Compile the function with the given name as the DirectX 11 hull shader. Replace <name> with the function name. This automatically adds #pragma require tessellation; for more information, see Targeting shader models and GPU features in HLSL.
#pragma domain <name> Compile the function with the given name as the DirectX 11 domain shader. Replace <name> with the function name. This option automatically turns on #pragma require tessellation; for more information, see Targeting shader models and GPU features in HLSL.

Shader variants and keywords

Use these directives to tell the shader compiler how to handle shader variants and keywords. For more information, see Declaring and using shader keywords in HLSL.

Directive Description
#pragma multi_compile <keywords> Declares a collection of keywords. The compiler includes all of the keywords in the build.

You can use suffixes such as _local to set additional options.

For more information and a list of supported suffixes, see Declaring and using shader keywords in HLSL.
#pragma shader_feature <keywords> Declares a collection of keywords. The compiler excludes unused keywords from the build.

You can use suffixes such as _local to set additional options.

For more information and a list of supported suffixes, see Declaring and using shader keywords in HLSL.
#pragma hardware_tier_variants <values> Built-in Render Pipeline only: Add keywords for graphics tiers when compiling for a given graphics API. For more information, see Graphics tiers.
#pragma skip_variants <list of keywords> Strip specified keywords.

GPU requirements and shader model support

Use these directives to tell the compiler that your shader requires specific GPU features.

Statement Function
#pragma target <value> The minimum shader model that this shader program is compatible with. Replace <value> with a valid value. For a list of valid values, see Shader compilation: Targeting shader models and GPU features in HLSL.
#pragma require <value> The minimum GPU features that this shader is compatible with. Replace <value> with a valid value, or multiple valid values separated by a space. For a list of valid values, see Shader compilation: Targeting shader models and GPU features in HLSL.

Graphics APIs

Use these directives to tell Unity to include or exclude code for a given graphics API.

Statement Function
#pragma only_renderers <value> Compile this shader program only for given graphics APIs. Replace <values> with a space-delimited list of valid values. For more information and a list of valid values, see Targeting graphics APIs and platforms in HLSL.
#pragma exclude_renderers <value> Do not compile this shader program for given graphics APIs. Replace <value> with a space-delimited list of valid values. For more information and a list of valid values, see Targeting graphics APIs and platforms in HLSL.

Other pragma directives

Statement Function
#pragma instancing_options <options> Enable GPU instancing in this shader, with given options. For more information, see GPU instancing
#pragma once Put this directive in a file to ensure that the compiler includes the file only once in a shader program.

Note: Unity only supports this directive when the Caching Shader Preprocessor is enabled.
#pragma enable_d3d11_debug_symbols Generates shader debug symbols for supported graphics APIs, and disables optimizations for all graphics APIs. Use this for debugging shader code in an external tool.

Unity generates debug symbols for Vulkan, DirectX 11 and 12, and supported console platforms.

Warning: Using this results in an increased file size and reduced shader performance. When you have finished debugging your shaders and you are ready to make a final build of your application, remove this line from your shader source code and recompile the shaders.
#pragma skip_optimizations <value> Forces optimizations off for given graphics APIs. Replace <values> with a space-delimited list of valid values. For a list of valid values, see Targeting graphics APIs and platforms in HLSL
#pragma hlslcc_bytecode_disassembly Embed disassembled HLSLcc bytecode into a translated shader.
#pragma disable_fastmath Enable precise IEEE 754 rules involving NaN handling. This currently only affects the Metal platform.
#pragma editor_sync_compilation Force synchronous compilation. This affects the Unity Editor only. For more information, see Asynchronous Shader compilation.
#pragma enable_cbuffer Emit cbuffer(name) when using CBUFFER_START(name) and CBUFFER_END macros from HLSLSupport even if the current platform does not support constant buffers.

Use a define_for_platform_compiler directive

Use a #define_for_platform_compiler directive in your shader code to send a #define directive to the shader compiler.

For example, #define_for_platform_compiler EXAMPLE_SYMBOL sends a #define EXAMPLE_SYMBOL directive to the shader compiler that defines a symbol called EXAMPLE_SYMBOL. Refer to external shader compiler documentation, for example Microsoft’s documentation on the FXC compiler, for more information about symbols that shader compilers use.

The Unity preprocessor doesn’t use symbols you define with #define_for_platform_compiler, so you can’t use the symbols in your own shader code. For example, in the above example, if you add shader code inside an #if (EXAMPLE_SYMBOL) statement, the code won’t run.

include and include_with_pragmas directives in HLSL
Targeting shader models and GPU features in HLSL