Version: 2020.2
Surface Shaders with DX11 / OpenGL Core Tessellation
Vertex and fragment shader examples

Writing vertex and fragment shaders

ShaderLabUnity’s declarative language for writing shaders. More info
See in Glossary
shaders describe properties that the Material InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary
displays, contain multiple shaderA small script that contains the mathematical calculations and algorithms for calculating the Color of each pixel rendered, based on the lighting input and the Material configuration. More info
See in Glossary
implementations for different graphics hardware, and configure fixed function hardware states. Programmable shaders like vertex and fragment programs, are just a part ShaderLab’s shader concept. This page outlines the low-level hardware shaders shader programs.

If you want to write shaders that interact with lighting, see the Surface ShadersUnity’s code generation approach that makes it much easier to write lit shaders than using low level vertex/pixel shader programs. More info
See in Glossary
documentation. For some examples, see the Vertex and Fragment Shader Examples. The rest of this page assumes shaders do not interact with Unity lights like special effects and post-processed effects.

Shader programs are written in HLSL language, by embedding snippets in the shader text, inside the Pass command. They usually look like this:

  Pass {
      // ... the usual pass state setup ...
      
      CGPROGRAM
      // compilation directives for this snippet, e.g.:
      #pragma vertex vert
      #pragma fragment frag
      
      // the Cg/HLSL code itself
      
      ENDCG
      // ... the rest of pass setup ...
  }

HLSL snippets

HLSL program snippets are written between CGPROGRAM and ENDCG keywords, or alternatively between HLSLPROGRAM and ENDHLSL. The latter form does not automatically include HLSLSupport and UnityShaderVariables built-in header files.

At the start of the snippet, compilation directives can be given as #pragma statements. The following table outlines directives that indicate which shader functions to compile:

Statement Function
#pragma vertex name Compile function name as the vertex shader.
#pragma fragment name Compile function name as the fragment shaderThe “per-pixel” part of shader code, performed every pixel that an object occupies on-screen. The fragment shader part is usually used to calculate and output the color of each pixel.
See in Glossary
.
#pragma geometry name Compile function name as DX10 geometry shader. This option automatically turns on #pragma target 4.0 as described in the table below.
#pragma hull name Compile function name as DX11 hull shader. This option automatically turns on #pragma target 5.0, as described in the table below.
#pragma domain name Compile function name as DX11 domain shader. This option automatically turns on #pragma target 5.0, as described in the table below.

Other compilation directives:

Statement Function
#pragma target name Set which shader target to compile to. For more information, see the Shader Compilation Targets documentation.
#pragma require feature ... A fine grain control on which GPU features a shader needs. For more information, see Shader Compilation Targets documentation.
#pragma only_renderers space separated names Compile shader only for given renderers. By default shaders are compiled for all renderers.
#pragma exclude_renderers space separated names Does not compile shader for given renderers. By default the system compiles shaders for all renderers.
#pragma multi_compile ... Use if you are working with multiple shader variants. Unused variants of multi_compile shaders are included in the game build.
#pragma multi_compile_local ... This statement is similar to multi_compile, but enumerated keywords are local. See the Making multiple shader program variants: Keyword limits documentation for more information.
#pragma shader_feature ... Use if you are working with multiple shader variants. Unused variants of shader_feature shaders are not included in the game build.
#pragma shader_feature_local ... This statement is similar to shader_feature, but enumerated keywords are local. See the Making multiple shader program variants: Keyword limits documentation for more information.
#pragma enable_d3d11_debug_symbols Generate debug information for shaders compiled for DirectX 11. This allows you to debug shaders via the Visual Studio 2012 (or higher) Graphics debugger.
#pragma hardware_tier_variants renderer name Generate multiple shader hardware variants of each shader the system compiles for each hardware tier that can run the selected renderer.
#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 glsl_es2 Set in a GLSL shader to generate a GLSL ES 1.0(OpenGL ES 2.0), even when the shader target is OpenGL ES 3.
#pragma editor_sync_compilation Force synchronous compilation. This affects the Unity Editor only.
#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.

Each snippet must contain at least a vertex program and a fragment program, so #pragma vertex and #pragma fragment directives are required.

The following compilation directives don’t do anything and can be safely removed:

  • #pragma glsl
  • #pragma glsl_no_auto_normalization
  • #pragma profileoption
  • #pragma fragmentoption.

Unity only supports #pragma directives in the shader files, and not in the includes.

Rendering platforms

Unity supports several renderingThe process of drawing graphics to the screen (or to a render texture). By default, the main camera in Unity renders its view to the screen. More info
See in Glossary
APIs, like Direct3D 11 and OpenGL, and by default Unity compiles all shader programs into all supported renderers. You can indicate which renderers to compile by using #pragma only_renderers or #pragma exclude_renderers directives. This is useful in cases when you use some shader language features that you aren’t possible on some platforms. Supported renderer names are:

Statement Renderer
d3d11 Direct3D 11/12
glcore OpenGL 3.x/4.x
gles OpenGL ES 2.0
gles3 OpenGL ES 3.x
metal iOSApple’s mobile operating system. More info
See in Glossary
/Mac Metal
vulkan Vulkan
d3d11_9x Direct3D 11 9.x feature level, as commonly used on WSA platforms
xboxone Xbox OneMicrosoft’s eighth generation video game console.
See in Glossary
ps4 PlayStation 4Sony’s eighth generation video game console.
See in Glossary
n3ds Nintendo 3DS
wiiu Nintendo Wii UNintendo’s eighth generation video game console.
See in Glossary

In the example below, this line would only compile a shader into D3D11 mode:

#pragma only_renderers d3d11

See Also


  • 2019–05–17 Page amended
  • Shader #pragma directives added in Unity 2018.1
Surface Shaders with DX11 / OpenGL Core Tessellation
Vertex and fragment shader examples