Back to Writing
NOTESunityshadersshaderlabcghlslgame-dev

Shaders - 06. Unity ShaderLab

April 9, 2020Updated Feb 17, 2026

![](

wc0LWquE-8o1ZQXvb0g.u0Y_pXlLUcS3tMy11NTDwIktgu-BiThBIU4ziXS_dHgg.PNG.cdw0424/image.png?type=w966)

This time we'll cover ShaderLab, the shader language written in Unity, and its overall structure.

When writing shaders in the Unity engine, you can choose to use CG, HLSL, or GLSL.

CG is primarily used, and all three languages are written together in a language called ShaderLab.

ShaderLab serves as the bridge that connects shader code like CG or HLSL with material files.

To apply a shader to a material in Unity, you must write ShaderLab code alongside it.

// The file extension for generated shader files is ".shader", and it's the same for both fragment shaders and surface shaders.

![](

JxSw_qNd8pjtqVI51wg.jxsAL_NlpZVGhDD_mwgcK2x7Ku_wSczLjdOFOlUk0wEg.PNG.cdw0424/image.png?type=w966)

What you're seeing here is a fragment shader used in Unity.

Let's group the parts and understand their roles.

![](

r9uA30LyEErEoHi4qMg.oVbjKduUntBX0X5f-sIEnAogbC_G7IOORRKTVvgH2Ukg.PNG.cdw0424/image.png?type=w966)

At the very top, Shader is a convention — it means the code written after Shader is a shader,

![](

og.VKMHTgGnEHbLVrjqvR0tZmPOwuI7ihc0ARkZixxKTU0g.PNG.cdw0424/SE-0287c455-3589-4eae-8f7a-1e108d3e4351.png?type=w966)

and the part written after Shader is the path and name of the shader file visible in the material.

![](

8g.v26nnewLZ_BbASpxDl_NurkMhdCpmT2bA8P6f0Y0IVsg.PNG.cdw0424/SE-9aef8a41-d183-401e-8955-f1f968a72392.png?type=w966)

The catch is that this name doesn't have to match the actual shader file name at all. For example, even if the shader file is named "Gold," if you write "Wood," you'd have to search for "Wood" in the material. There's no reason to do something this confusing on purpose, but since people make mistakes, it's best to match the file name whenever possible.

![](

j8iWBX4SJ_5vyqxZ_4g.D9Hp_bW8TlMwsKqTYoduL-sKM8DgHOXFTwu8zMwGvvAg.PNG.cdw0424/image.png?type=w966)

Next, these Properties connect variables from the actual shader code (like CG or HLSL) to the material as parameters.

In simple terms, if the shader's variables are like a radio's volume control, the variables written in Properties are the volume control knobs.

![](

QvBJLVij714BmI26dMg.ajjC__0pUBCC-uIBISDLZE5JWj2ytn1vuKySRjCwy7sg.PNG.cdw0424/image.png?type=w966)

Like this.

![](

ONPWhkTG75X_Acg.01-ZRgKZlXi4T7kWY8mfoJQWYLepNyWYQc1aXXMdz2Yg.PNG.cdw0424/image.png?type=w966)

Next, the Tags directly below SubShader let you configure the rendering order and various features,

and from Pass onward, you can write the actual shader code.

The circled section here is the configuration part,

![](

PquoGW3tFOVDi1gDZog.yNYNV5X4NHBt0LkRBc-7W-UVA5iGsH3G5HH8BlMQA3cg.PNG.cdw0424/image.png?type=w966)

and this Pass section is where the actual shader code goes.

Pass { shader code... }

Pass { shader code... }

If there are two passes like this, both shaders are applied once each, rendering twice.

Getting back on track — directly below Pass you'll see CGPROGRAM, which means "CG language starts here".

![](

NQrQReMwt3YGlyO0RUg.MSWhxz9Ps9BSqCilbhHXYN8-jnF4G_6pWHgSIfvgWiEg.PNG.cdw0424/image.png?type=w966)

And below you'll see ENDCG — everything written between CGPROGRAM and ENDCG is CG code.

So for HLSL, it would be HLSLPROGRAM,

and for GLSL, GLSLPROGRAM.

![](

Y56egEZIsBgMuACQZ8g.GnrPuZc36Kt14x9fZJFWWiZEGbd77uI85AMpcuJBuQcg.PNG.cdw0424/image.png?type=w966)

Below you'll see syntax very similar to C/C++.

#pragma is a configuration directive.

For example, #pragma vertex vert means the function that processes vertices is named vert.

You can look up and apply pragma directives as needed.

Next, #include "UnityCG.cginc" means we're using the various functions and variable names from Unity's CG library.

Think of it like using a using statement in C#. GLSL and HLSL have different file names, so search and use them as needed.

So far we've taken a broad look at the structure. Next time, we'll analyze the CG syntax.