ShaderLab shaders encompass more than just “hardware shaders”. They do many things. They describe properties that are displayed in the Material Inspector, contain multiple shader implementations for different graphics hardware, configure fixed function hardware state and so on. The actual programmable shaders - like vertex and fragment programs - are just a part of the whole ShaderLab’s “shader” concept. Take a look at shader tutorial for a basic introduction. Here we’ll call the low-level hardware shaders shader programs.
If you want to write shaders that interact with lighting, take a look at Surface Shaders documentation. For some examples, take a look at Vertex and Fragment Shader Examples. The rest of this page assumes shaders do not interact with Unity lights (for example special effects, post-processed effects etc.)
Shader programs are written in HLSL language, by embedding “snippets” in the shader text, somewhere 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 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. Directives indicating which shader functions to compile:
Other compilation directives:
Each snippet must contain at least a vertex program and a fragment program. Thus #pragma vertex and #pragma fragment directives are required.
Compilation directives that don’t do anything starting with Unity 5.0 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.
Unity supports several rendering APIs (e.g. Direct3D 11 and OpenGL), and by default all shader programs are compiled into all supported renderers. You can indicate which renderers to compile to using #pragma only_renderers or #pragma exclude_renderers directives. This is mostly useful in cases where you are explicitly using some shader language features that you know aren’t possible on some platforms. Supported renderer names are:
For example, this line would only compile shader into D3D11 mode:
#pragma only_renderers d3d11
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thanks for helping to make the Unity documentation better!