A shader is a small program that contains instructions for the GPU. It describes how to calculate screen color for a specific material.
Although Unity has a Standard Shader, sometimes you need to implement an effect that a standard shader is not capable of.
Previously, this required knowledge of a specific shader language, such as Cg or HLSL, and the approaches in them are slightly different from the usual creation of gameplay scripts. For many people, writing shaders is an unpopular aspect of game development, because it requires the development of an additional learning curve.
Unity introduced
Shader Graph , which makes it easier to write shaders with almost no code. Best of all, Shader Graph allows you to work with a visual interactive interface.
In this tutorial, you will create your first Unity shader!
Getting to work
This tutorial uses Unity version 2019.1 or newer. Download the new version of Unity
here .
Note : although this tutorial is intended for beginners in Shader Graph, it assumes that you know the basics of development in Unity and have mastered the interface of the engine. If you're new to Unity, then check out the excellent Getting Started In Unity tutorial.
Download the tutorial materials
here . Then unzip the contents and open
Intro to Shader Graph Starter in Unity.
The
RW folder in the Project window is organized as follows:
- Fonts : Fonts used in the scene.
- Materials : materials for the scene.
- Models : 3D meshes for game shapes and backgrounds.
- PostFX : post-processing effects for scene rendering.
- Prefabs : various pre-built components.
- Scenes : game scene.
- Scripts : scripts with game logic.
- Shaders : Shader graphs created for this tutorial.
- Sprites : a sprite used as part of the instructions.
- Textures : texture maps for game shapes and backgrounds.
Now load the
TangramPuzzle scene from the
Scenes folder.
This is a simple game called
Tangram , which appeared in China in the 19th century. The player's task is to move seven flat geometric shapes, making them stylized pictograms or silhouettes.
Launch
Play mode in the editor and test the demo games.
You can click on the shapes and drag them. Use direction keys to rotate shapes. Rotate and shift the shapes so that they do not overlap each other.
Can you figure out how to move the seven shapes to create such patterns?
So, from a
technical point of view, the game works, but it does not give any visual feedback about the selected figure.
What if we can make the shape glow when a mouse is over it? This will improve the user interface.
And this is a great chance to demonstrate the capabilities of Shader Graph!
Checking pipeline parameters for Shader Graph
Shader Graph only works with the relatively new
Scriptable Render Pipeline , i.e. with the
High-Definition Render Pipeline or with the
Lightweight Render Pipeline .
When creating a new project for working with Shader Graph, select the correct template.
The sample project is already configured to work with the
Lightweight Render Pipeline . First, confirm in PackageManager that you have
Lightweight RP and
ShaderGraph installed by choosing
Window ► PackageManager .
Then select one of the available versions and, if necessary, click the
Update to button. Usually the best option is the latest
verified version.
After updating the packages, carefully check the correctness of the pipeline parameters in
Edit ► Project Settings .
On the
Graphics tab, the
Scriptable Render Pipeline Settings parameter should be set to
LWRP-HighQuality . Thanks to this, the project will use the highest default setting for the Lightweight Render Pipeline.
After making sure that you are using one of the
Scriptable Render Pipeline assets, close this window.
Creating PBR Graph
When rendering a 3D mesh to the screen, the material and the shader always work together. Therefore, before starting to create a shader, we need material.
First, click the
Create button in the Project window to generate a new material in the
RW / Materials folder. Select
Create ► Material , and then rename it to
Glow_Mat .
Then, in the
RW / Shaders folder, create a
PBR Graph by choosing
Create ► Shader ► PBR Graph . This is a shader graph that supports
physically accurate rendering , or PBR.
Name it
HighlightShaderGraph .
Material Glow_Mat so far uses a standard shader for
LightweightRenderPipeline called
LightweightRenderPipeline / Lit.Change it to the newly created new shader graph. With
Glow_Mat selected, click on the
Shader drop-down menu at the top of the inspector and select
Shader Graphs ► HighlightShaderGraph .
Glow_Mat will take on a slightly lighter shade of gray, but otherwise remain pretty dull. Don’t worry, we will fix it soon.
Now double-click on the
HighlightShaderGraph asset or click on the
Open Shader Editor in the inspector. This will open the
Shader Graph window.
Check out the main parts of this interface:
- The main workspace is a dark gray area in which graph operations will be stored. You can right-click on the workspace to open the context menu.
- A node is a single element of a graph. Each node has an input, output, or operation, depending on its ports. Nodes are connected to each other using edges .
- Master node is the last output node of the graph. In this example, we use a physically accurate rendering option, also called the PBR Master node. You may notice certain properties in it, such as Albedo, Normal, Emission, and Metallic, which are used in Standard Shader.
- Blackboard can provide access to certain parts of the graph in the inspector. This allows the user to configure parameters without directly editing the graph itself.
- Main Preview interactively displays the current output of the shader as a sphere.
By connecting the various nodes, you can create a
shader graph that Unity compiles and transfers to the GPU.
Creating a Color node
First, let's give the shader some basic color. To do this, connect the color node with the Albedo component of the PBR Master node.
Right-click on the workspace to create the first node from the context menu by choosing
Create Node ► Input ► Basic ► Color .
Notice that there are hundreds of nodes in the
Create Node menu! At first it seems confusing, but you will soon figure out the most actively used ones.
Next, drag the node over the workspace, holding on to its title bar. Then leave it somewhere to the left of the
PBR Master node.
The
Color node allows you to specify a single color. Click on the color field and select a beautiful red hue, for example
R: 128, G: 5, B: 5 .
To output the color to the
PBR Master node, drag the
Out port to the
Albedo port, which indicates the base color of the shader.
By connecting the nodes edge-by-side, you should see how the sphere in the
Main Preview turns red.
Excellent! In the area of writing shaders, creating a single-color shader is an analogue of
Hello, world!Although you may not understand this yet, but you just created your first shader!
Work with the interface
Although there are only a couple of nodes in the graph, now is the best time to get comfortable with the Shader Graph interface.
Try dragging the nodes and notice that the edges between the
Color output port and the
PBR Master input port remain connected.
Nodes can contain various types of data. Just as we created a node containing a single input color, we can create a node representing a single number; Select
Create Node ► Input ► Basic ► Integer . We will not do anything with this node; it is needed only to illustrate the principle.
Connect the
Integer Out port to the
Alpha port of the
PBR Master node.
Our graph is still very small, but we already have enough nodes to check the action of the hot keys. Select a pair of nodes and press the following keys:
- F : frame the selected nodes.
- A : frame the entire graph.
You can also use the buttons at the top of the window to switch between
Main Preview and
Blackboard . The
Show in Project button helps to find the current shader graph in the Project window.
Having dealt with the management of the graph, we clean it. All we need is the
Color and
PBR Master nodes.
Right-click the connection between the
Integer and
Master nodes, and then select
Delete . This will separate the node from the graph.
Similarly, you can delete the
Integer node entirely. Right-click on the node and select
Delete .
When finished, click on the
Save Asset button in the upper left corner of the interface. Unity will save all changes, and then compile and activate the shader. This step should be done every time you want to see the latest changes in the editor.
Now go back to the window and select the
Glow_Mat material.
As the shader extends to the material, the sphere in the inspector's preview window should turn red.
Now drag the
Glow_Mat material
onto the tangram shapes in the
Scene window.
As expected, the material with the shader painted the mesh in a beautiful, uniform red color.
Add a glow effect
If you want the Glow_Mat material to have a more mysterious glow, you need to edit the shader graph again.
Now the
Color output is transferred to the input of the
Albedo PBR Master node.
You can also drag another edge from
Out to
Emission . Now the same color is used twice: both as the base color and as the color of the radiation.
Output ports can have multiple edges, and input ports can have only one.
Now switch the
Mode drop-down menu of the
Color node to
HDR mode. So we will include the
extended dynamic range of colors.
Now change the color field. In
HDR Mode , an additional
Intensity option has appeared. Click
+1 a couple of times in the bottom palette or drag the slider about
2.5 . Now save the changes and return to the editor.
In the editor, the figure will glow in bright orange. Post-processing in the scene is already on and it enhances the color of the extended dynamic range.
Now select the game object
PostProcessing in the hierarchy. The glow is due to the
Bloom effect.
Open the
Bloom options and set the
Intensity (luminous strength) and
Threshold (threshold for the onset of luminescence). The example shows the values
3 and
2 .
Wow, this shine!
Creating a highlight script
We do not want the figure to glow constantly. We need the glow to turn on only depending on the position of the mouse.
When the mouse cursor is over the shape, we must enable the Glow_Mat material. In other cases, the figure should be displayed with the standard material Wood_Mat.
First, create a new
C # script in
RW / Scripts and call it
Highlighter . He will help us switch between the two materials during the execution of the program. Replace all lines in the script with the following code:
using UnityEngine;
Let's parse this script:
- The script can only be applied to an object containing the components
MeshRenderer
and Collider
. This is controlled by adding the [RequireComponent]
attributes to the top of the script. - These are links to
MeshRenderer
, originalMaterial
and highlightedMaterial
. Materials are marked with the [SerializeField]
attribute, which allows you to assign them from the inspector. - In the
Start
method, we automatically populate the MeshRenderer
using GetComponent
. - Called
EnableHighlight(false)
. This ensures that, by default, non-highlighted content is displayed. Below is the public EnableHighlight
method, which switches the renderer material. It receives the boolean parameter onOff
, which determines the state of the backlight. - Preventing All NullReference Errors
- To save space, we use the ternary operator.
Add mouse events
Since this script applies to shapes that have a
MeshCollider
, we can use the built-in methods
OnMouseOver
and
OnMouseOver
. Add the following code after the
EnableHighlight
method:
private void OnMouseOver() { EnableHighlight(true); } private void OnMouseExit() { EnableHighlight(false); }
When the mouse is over the shape, it will call
EnableHighlight(true)
. Similarly, when the mouse leaves Collider, it will call
EnableHighlight(false)
.
That's all! Save the script.
Figure highlight
If in the previous sections of the tutorial you applied Glow_Mat to any of the figures, then in the editor you need to return Wood_Mat material to all game figures. Now, to turn on the glow, we will use
Highlighter while the program is running.
First, we’ll select seven objects inside the transform
Tangram , which are separate shapes. Then we add to them all the
Highlighter
script at the same time.
Then drag
Wood_Mat into the
Original Material field and
Glow_Mat into the
Highlighted Material field . Now run the
Play mode and check the result of our work.
Not bad! When you hover over the tangram shape, it begins to glow in bright red. If you remove the cursor from it, it returns to its original state.
In the game itself, nothing has changed, but the highlight effect added visual interest and allows the player to focus.
Using texture nodes
At the moment, our simple shader has a solid bright red color. We will change the shader so that it does not lose its original wood texture. To do this, we will make the backlight appear as a luminous edge
around the surface.
First, change the
HighlightShaderGraph by double-clicking on it or selecting
in the
Open Shader Editor .
Delete the
Color node by
right-clicking on it and selecting
Delete . We will create everything from scratch.
Instead of a single color, we substitute the texture using the
Sample Texture 2D node.
Create a node, either from the context menu,
by right-clicking and choosing
Create Node , or by using a hot key (space). Select
Input ► Texture ► Sample Texture 2D .
The
Sample Texture 2D node reads color information from a texture asset and outputs its RGB values.
Select a texture from the
Texture input port. Click on the dot next to the empty field to open the file browser.
Select the WoodAlbedo texture
asset .
Connect the
RGBA output port of the
Sample Texture 2D node to the
PBR Master Albedo port.
Voila! Now the texture of the tree is displayed on the surface of the preview sphere.
If you add a normal map, you can create parts on the surface. First, create another
Sample Texture 2D node by choosing
Create Node ► Input ► Texture ► Sample Texture 2D .
Select a
WoodNormal texture in the Texture input port.
Change the
Type drop-down menu from
Default to
Normal .
Output the
RGBA values to the
Normal port of the
PBR Master node.
The scope of the
Main Preview should now look more rough. The normal map imitates small irregularities and indentations on the surface. This allows you to simulate the appearance of a tree.
Note : the data type of each port is indicated in parentheses next to the port. (T2) means that the port is compatible with two-dimensional texture, and (4) means that the port uses Vector4 . Depending on the context, the Shader Graph may ignore extra floating point values.
Adding the Fresnel Effect
Now that the solid red color has changed to the base texture and normal map, let's add a highlight effect using another method.
Instead of a uniform glow of the entire object, we will limit the glow to its edges only. This can be realized using
the Fresnel effect .
Create a new node by
right-clicking or spacebar, and then select
Create Node ► Math ► Vector ► Fresnel Effect .
This new node shows a sphere with a white radiant ring in diameter. You can adjust the width of this halo using the
Power input port. Click and drag the
X to the left of the field or enter the numbers you want.
The larger the value, the thinner the halo becomes, and the smaller values make it very wide. To create a subtle glow around the edge, you can use the value
4 .
To convey this halo to the material, we will connect the
Fresnel Effect output to the
Emission input of the
PBR Master node.
Now,
MainPreview displays a wooden sphere with a bright white halo, obtained thanks to the
Fresnel Effect .
Note : The Fresnel effect is named after the French physicist Augustin Jean Fresnel. He noticed that the light makes the surfaces very bright and look like a mirror when an observer approaches a glide angle .
You can experiment with the kitchen table. We use the Unity version of this phenomenon to give geometry a radiance.
Multiplication by Color
You can add colors to the luminous contour using simple color calculations.
Create a new color node that will indicate the color of the luminous ring.
Right-click or spacebar to open the context menu, and then select
Create node ► Input ► Basic ► Color . Switch the color mode to
HDR .
Select a color that will indicate the color of the backlight. For example, choose a beautiful bright green:
R: 5, G: 255, B: 5 .
Increase
Intensity to
3.5 .
We cannot combine the new color with the Fresnel effect. because it has no input for color. Therefore, we will need to combine the output of the effect with the output of the color node. This can be done using the
Multiply node.
Create a
Multiply node by
right-clicking , and then select
Create node ► Math ► Basic ► Multiply .
Delete the edge between the
Fresnel Effect and the
PBR Master . Connect the
Fresnel Effect output to the
A input of the
Multiply node.
Connect the
Out node of the
Color node to the input
B of the Multiply node.
Then connect
Out of the Multiply node to the
Emission port of the
PBR Master node. Voila! Now we see how the bright green HDR color surrounds the
Main Preview sphere.
Remember that you can use
Fresnel Effect Power to increase or decrease the halo. If you reduce the value to 1.5, you get a wide green glow.
For our game example, a value from
4 to
5 is good, but you can experiment with your values.
Save the shader graph and return to the editor. You will immediately see your
HighlightShaderGraph in action.
Launch
Play Mode.
When you hover over a shape, it retains its tree texture. However, a bright green glow has now appeared around its edges. Formally, nothing has changed in the game, only the backlight has become weaker.
Add Blackboard Properties
If you want to change the appearance of the glow effect, you need to return to the Shader Graph editor window and make these changes. For example, using
Fresnel Effect Power, expand or narrow the halo band.
This is not very convenient if we want to test various changes. Fortunately, Shader Graph has a concept for properties.
You can make part of the graph publicly visible in the inspector, which allows you to make small changes interactively. This is done using the
Blackboard interface.
Go back to the Shader Graph and turn on the
Blackboard display. If it is hidden, then click the
Blackboard button in the upper right corner.
Adding Base Texture and Normal Map Properties
Now we will open both the base texture and the normal map so that they can be accessed through the inspector.
Click the
+ icon in the upper right corner of the
Blackboard . Select
Texture 2D from the drop-down list. The item should appear on the
Blackboard . Rename it to
BaseTexture .
Make sure the
exposed checkbox is checked. If you open a property, it will become public and accessible in the inspector.
To add a property to the graph, simply drag it by the label into the workspace. Leave it somewhere to the left of the
Sample Texture 2D node.
Connect the
BaseTexture port to the
Texture input port of the
SampleTexture 2D node that is connected to Albedo. This will replace the previous setpoint.
Repeat the same process for
Normal Map . Click on the
+ icon and create a new
Texture 2D . Rename it to
Normal Map .
Drag the property into the workspace and attach it to the
Sample Texture 2D for the normal map.
Click
Save Asset and return to the main editor window.
Select the
Glow_Mat material and notice two new fields in the inspector:
Base Texture and
Normal Map .
Since no texture has been set for them yet, a green highlight over the gray sphere is displayed in the preview window.
Select
WoodAlbedo and
WoodNormal for BaseTexture and
NormalMap .
Now, under the luminous edges, the texture of the tree will be displayed correctly.
Public properties allow the user to enter data directly into the shader without the need to edit the shader graph. Experiment on your own with a selection of different basic textures and normal maps.
Add properties Glow Size and Glow Color
Now we will reveal other types of properties in Blackboard. For example, it will be useful to let the Fresnel Effect Power value change.
Click the
+ icon on
Blackboard and create the
Vector1 property. It denotes a single parameter of type float.
Rename it to
GlowSize .
You can limit the range of values entered for this property by converting it into a
slider . Switch
Mode to
Slider , and then set
Min to
0.05 and
Max to
6 to specify a range. Set the
Default value to
5 .
Drag the
GlowSize property into the workspace. Connect the output port to the
Fresnel Effect Power input.
Now let the user set the color of the glow. Instead of creating a property in Blackboard, we transform the existing node in the graph.
Select the
Color node, then
right-click and select
Convert to Property .
The
Color node is converted to a color property in the
Blackboard , which can no longer be changed directly in the graph. Rename the property to
GlowColor .
Click
Save Asset and return to the main editor window.
Select the
Glow_Mat material in the Project window. You should see that the
GlowSize slider and the
GlowColor field are now available in the inspector.
Change the material values to your taste. Launch
Play mode to test your work.
Now you have a customizable backlight that can be changed as you wish!
Where to go next
Congratulations! Now you can create your own shaders using the Shader Graph!
Using your own creative abilities, you yourself will be surprised that you will succeed. Want to create a cool fantastic laser beam or force field? Adapt the result of our work to the shader you need.
Although there are literally hundreds of nodes, this tutorial should have helped you learn Shader Graph.