How translation works
Shader code is written in C#, but it doesn't run as C#. When Unity compiles your scripts, Shader Script translates the code of each shader into HLSL, the language Unity shaders are written in, and the GPU runs that. This page explains what that means for the code you write.
A subset of C#
Shader code uses a subset of C# that maps directly to HLSL:
- Types are GPU types.
float3in C# isfloat3in HLSL,math.sinis HLSL'ssin,Texture2D.Sampleis a texture sample. The C# types exist so that the compiler and your IDE understand the code. - Everything is a value. GPUs have no heap and no garbage collector, so there are no classes, strings, delegates or C# arrays in shader code. Vectors, matrices, fixed-size arrays and your own structs are copied on assignment, as structs in C# are.
- Methods become HLSL functions. Helper methods, overloads, and
ref,outandinparameters work as in C#. The GPU compiler usually inlines all of them. - Constants disappear.
constvalues and enum values are replaced by their values in the generated code.
What C# features are supported, and what isn't, is described in the following pages and summarized in What's not supported.
Where shader code lives
- The shader class. Its
Vert,FragandDisplacemethods, its helper methods, and its constants. The class's properties aren't code: they declare material properties, and must be written as{ get; }. [ShaderCode]types. Static classes and structs with code shared between shaders. See Shared code.
A shader class can't have fields, except const ones.
Errors come from the C# compiler
Shader Script checks the code while it's being compiled, and reports anything it can't translate as a regular C# compiler error, in your IDE and in the Unity Console. Each error has a code, such as SSG1002, and a message that says what to change. See Diagnostics for the full list.
Some mistakes only show up when Unity compiles the generated shader, as shader errors in the Console. Double-clicking one opens the generated code at the failing line. See Debugging.
Names
Names in shader code can't contain underscores, whether of types, methods, properties, local variables, parameters, fields or constants: Shader Script uses underscores in the names it generates.
Shader code doesn't run in C#
The shader class is an ordinary C# class, but calling its methods from your game code does nothing useful: the functions of ShaderApi and ShaderLib, the textures and the built-in variables only work on the GPU. The math functions, the scalar, vector and matrix types and the arrays do work in C#, with the same behavior as on the GPU, which lets you test pure math, but the shader itself runs only on the GPU.