Introduction to Shaders in Unity
Ever wondered about shaders in Unity? In this tutorial, you’ll learn what shaders are, how to display vertex colors and how to animate within shaders. By Joseph Hocking.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Introduction to Shaders in Unity
25 mins
- What Are Shaders?
- Understanding Types of Shaders
- Writing a Custom Shader
- Looking at the Default Template for a Custom Shader
- Properties
- The SubShader block
- The CGPROGRAM block
- MainTex property variable
- Inputs and property variables
- The main shader function
- FallBack shader
- Adding Vertex Color to a Surface Shader
- Creating a Custom Shader for Vertex Color
- Animating the Water Texture
- Creating an Unlit Shader
- Where to Go From Here?
Unity provides a lot of help to game developers, and that includes offering Shaders to make complex VFX and animations easier. You can get pretty far just tinkering with the standard Shaders that come with Unity. However, you can enhance the visuals in your projects by writing custom Shaders.
In this tutorial, you’ll learn:
- What Shaders are.
- How to display vertex colors.
- How to animate within Shaders.
To practice, you’ll be polishing the graphics of a desert island scene using custom Shaders. Download the project files by clicking on the Download Materials button at the top or bottom of this tutorial. The sample project provides models and textures so that you can concentrate on the Shaders.
The sample project uses Unity 2019.3, although everything in this tutorial should work in older versions as well.
What Are Shaders?
Computer graphics, especially 3D graphics, use many different kinds of information to construct the visuals: meshes, textures, lights and so on. That information passes to the graphics hardware, which then processes the image and displays it onto the screen.
Rendering is what programmers call the process of generating an image, and Shaders are short programs that render graphics data. That is, a Shader is a program that takes meshes, textures etc. as the input and generates an image as the output.
Understanding Types of Shaders
Technically, an individual Shader doesn’t output an entire image, nor do they always do rendering. Rather, there are different types of Shaders that do different things.
The main type is a Pixel Shader, named for the obvious reason that it outputs a pixel. Another common term is Fragment Shader, since each pixel is a fragment of the full image.
Fragment Shaders output a single pixel’s color, which it calculates based on that pixel’s position on a polygon. The program runs over and over, mostly in parallel, to generate all the pixels of all the polygons processed by that Shader. Indeed, being able to process more pixels simultaneously is a major part of how video cards accelerate graphics.
There are also Vertex Shaders, which you use to compute the position of vertices in the image. While the input data is in three dimensions, the computer needs to determine where the vertices appear in two dimensions before it can render the pixels.
You can achieve some interesting visual effects by manipulating the data output by Vertex Shaders, but you won’t cover that in this tutorial.
Compute Shaders don’t actually render anything, but are simply programs that run on video hardware. These Shaders are a recent innovation – indeed, older video hardware may not even support them.
As with Fragment and Vertex Shaders, a Compute Shader is a short program that the graphics card runs in a massively-parallel fashion. Unlike the other Shaders, Compute Shaders don’t output anything visual. Instead, they take advantage of the parallel processing in video cards to do things like cryptocurrency mining. You won’t work with Compute Shaders in this tutorial.
Unity introduces yet another kind of Shader, a Surface Shader. These are Shaders that do lighting calculations for you, and you only need to write code – remember, a Shader is a program – to handle other surface properties, like color and texture.
Surface Shaders are really Fragment and Vertex Shaders under the hood, but Unity generates code to handle lighting. This is handy since lighting calculations are both very complicated and frequently standardized between many different Shaders.
Finally, the graphics data tells the video card which Shader to use through materials. When you inspect a material, you’ll notice a menu at the top. That menu selects which Shader to assign to that material. Thus, when the graphics hardware renders a polygon, it runs the Shader of that polygon’s material.
Alright, enough explanation. It’s time to write some Shaders!
Writing a Custom Shader
If you haven’t already, open the begin project then open RW/Scenes/SampleScene. You’ll see a pre-constructed desert island scene, complete with positioned models that have materials assigned to them.
The existing scene doesn’t look terrible, but you can improve it in at least two ways: The island has hard, square edges, and the water is completely static.
You can solve both issues with custom Shaders. Before addressing those issues, however, you need to understand how to create Shaders.
To start with, create a Surface Shader asset in the Shaders folder by right-clicking and selecting Create ▸ Shader ▸ Standard Surface Shader. Name it MyFirstShader.
Go to the Materials folder, select cartoon-sand and click the Shader drop-down at the top of the Inspector. Select Custom ▸ MyFirstShader to switch the material to that Shader.
Nothing much will change in the scene yet because you haven’t changed any of the default Shader code. Nevertheless, the sand material on the island now uses your custom Shader rather than the standard Shader built into Unity.
Looking at the Default Template for a Custom Shader
Double-click the Shader asset to open it in your code editor, and examine the code.
The shader is made up of various sections inside the main Shader
block of code.
All the code is inside a Shader block with curly brackets, with the name Custom/MyFirstShader. This simply tells Unity what to show when browsing a material’s Shader menu. Looking at the different sections…
Properties
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
The Properties
block at the top is where you declare the various user-defined properties. These are the values you can edit in the inspector when you select a material.
Going over a single line in detail: First, you see the variable name used within the code. Next, inside parentheses, you define the name you’ll display in the inspector. Also inside the parentheses, you declare what type the property is: a color, a 2D texture or a number range. Finally, after the =
, you give the property a default value.