Introduction to Shader in Unity

Needone App
5 min readFeb 22, 2023

--

Many of us have heard or even used Shader in the Unity game, so in the next coming few weeks, we will go through few hot topics on the Shader. Of course, Shader is a great topic, a few articles probably won’t explain well, but good enough to get start with:

  • Introduction to Shader in Unity (This article): including the basic concept on what is Shader and what can they do
  • SubShader
  • Rendering Pipeline

What Shader can do in Unity

Shaders are short program that render graphics data which takes meshes, textures, etc as input and generates an image as output.

Shader is short program running on video card which used to render 3D models in a specific way, mostly in the visualisation, such as how the surface of a 3D model reacts to light and how it appears on screen, how the waves in the river/sea moves. Here is a list of what Shader can do in game development:

  • Change the color of an object
  • Transparency or translucency effects
  • Reflections
  • Create texture effects
  • Customise visual effects for particles and other objects
  • Create shadows and other lighting effects

Shaders can be written in a variety of languages, including Cg/HLSL, which is similar to C++, and ShaderLab, which is a language that is specific to Unity. Moreover, Unity already provides tons of pre-built shaders that can be used to achieve a variety of common effects.

Simple example of Unity Shader

To create a Shader in Unity is quite simple: Right clicking in the Assets window and selecting Create->Shader->Standard Surface Shader, named BlinkShader

Open the BlinkShader with any text editor, I do recommend to use the Visual code here, if you don’t how, check out this article: Setup Visual Studio Code for Unity on Mac 2022. Copy and paste the following Shader code:

Shader "Custom/BlinkShader"
{
Properties {
_MainColor ("Main Color", Color) = (1, 0, 0, 1)
_TimeSpeed ("Time Speed", Range(10, 20)) = 15
}

SubShader {
Tags {"Queue"="Transparent" "RenderType"="Opaque"}

Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

// Unity built-in variable that holds the position of the vertex in world space
float4 _WorldSpacePos;

// Properties
uniform float4 _MainColor;
uniform float _TimeSpeed;

struct appdata {
float4 vertex : POSITION;
};

struct v2f {
float4 vertex : SV_POSITION;
};

v2f vert (appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}

float4 frag () : SV_Target {
float4 color = lerp(float4(1, 0, 0, 1), float4(0, 0, 1, 1), sin(20 * _Time.y));
return color;
}

ENDCG
}
}
}hl

To make use of BlinkShader we need to create a new material, Right clicking in the Assets window and selecting Create->Material, name it as BlinkMaterial. Then on the BlinkMaterial’s inspector, choose the BlinkShader we just created.

Finally, attach the material BlinkMaterial to an game object, here I am using a lovely cube instead.

LET RUN THE GAME:

The Basic of Shader

With the example above, the Shader mainly includes the following parts, blocks or sections:

  1. Shader name
  2. Properties
  3. SubShaders
  4. FallBack
  5. CustomEditor

1. Shader Name

This is the first line of the Shader, which present the path of the Shader. Custom means this shader is under the Custom menu.

2. Properties

The texture displayed in the attribute and material sphere panels, as well as some parameters such as colour, are all defined and set in this “Properties” section, and the content must be written within the {} after “Properties”. Of course, if you are sure that you do not need the attributes, you can delete the entire “Properties” and its {} because it is optional.

“Properties” can be understood as the connection channel between the material and Shader. The things that need to be set on the material panel must be implemented and exposed through “Properties”.

[Attribute]_Name ("Display Name",Type) = Default Value

Attribute: Optional

_Name: We can understand this as variable name in other programming language. Normally we will put some gloabal variables here, such as colour, time and so on. Note that we must have the “_” in front of our name.

Display Name: This name will be displayed on the material’s inspector, see the following image, we have Main Color and Time Speed as the example above:

It is recommended to have some meaningful name in case we have a large amount of Shaders and Materials in the project.

Type: Shader name types. Like the variable in other programming, we normally associate a type for that variable. For example, int a = 1; in C programming language. We have tons of built-in types in Unity, here are some common used ones:

Properties {
_Color ("Color", Color) = (1,1,1,1) // Color, (R, G, B, )
_TimeSpeed ("Time Speed", Range(10, 20)) = 15 // value between 10 and 20
}

For more details on the Shader data types, check this article ( Shader Data Types) for more details.

3. SubShaders

Shader can contain at least one Subshader, and more than one Subshaders. As the Shader’s core function will be implemented by Subshader. When loading the Shader, Unity will scan all the Subshaders and select one that the device supported. It is quite useful when dealing with the scenario like we have low, medium and high end machine, some Shader may run well on the high end machine, but performs not that good on others. To deal with that, we then can have 3 SubShaders targeting each of the low, medium and high end machine accordingly.

4. Fallback

Optional. As the name indicate itself, it will tell the Shader that it is not supported or encounter any error, it will find other Shader with the given path.

5. CustomEditor

Provide an UI portal on editing properties. For example:

What is next

From next few articles, we will cover all the shader types in the Unity, such as Standard Surface Shader, Unlit Shader, Image Effect Shader, Compute Shader and Ray Tracking Shader.

Reference

1, https://docs.unity3d.com/Manual/SL-DataTypesAndPrecision.html

Originally published at https://hackingwithunity.com on February 22, 2023.

--

--