Unity Shader Graph: How to Create a PBR Shader
Physically Based Rendering, or PBR, is a rendering method that allows us to produce very realistically lit shaders. This article shows you exactly how to make a PBR shader using the Unity Shader Graph in Unity 6.
In previous articles I’ve described the Lambert, Phong, and Blinn-Phong lighting models but they are all considered the very old way of doing light rendering. The current way is to use a method called Physically Based Rendering, or PBR for short. This method of lighting takes in far more variables then the previous methods to produce much more realistic result.
Why is it Important?
When displaying any graphics on a screen, light plays an important role. A lack of light rendering can give a flat or cartoon feel where as more realistic light rendering can greatly enhance the viewing experience and realism.
On the left side of the above image we can see the results of a cube that isn’t rendering any lighting compared to the right side showing a cube using a PBR shader.
In this article we are going to do the following:
- Create a custom PBR shader using the shader graph
What you will need for this project:
- Textures for your shader(can be found for free online):
- Albedo
- Normal
- Roughness
- Ambient Occlusion
Want to skip the reading and avoid any mistakes? Get the entire solution now as either a Unity Package or a zip file of the entire project.
The Steps
Step 1: Create a new Unity URP project
Open up Unity Hub and create a new Unity URP project using Unity 6. Feel free to name it whatever you want. I will name mine “PBR Shader Graph.”
Step 2: Create a New Shader
Right-click the project hierarchy and select Create->Shader Graph->URP->Lit Shader Graph to create a new shader graph file.
Step 3: Creating Our Variables
A PBR shader is going to require quite a few variables to get the base results. It’s going to require four different textures and three float variables to adjust from within the Material. The variables we need are:
- Texture2D: “Albedo”
- Texture2D: “Roughness”
- Texture2D: “Ambient Occlusion”
- Texture2D: “Normal”
- Float: “Metalic”
- Float: “Smoothness”
- Float: “AO Slider”
To create new variables we need to open our new shader, make sure the Blackboard is open and then click the plus icon to create each new variable in the shader.
Once you add all of them, your black board should look like the following image.
Step 4: Creating Texture Samplers
Now we need to start creating nodes. The first nodes we are going to need will be nodes to sample the Texture2D variables we just made.
The easiest way to do this is to drag the variable out of the Blackboard and onto the graph. That will create a new variable node. Then we can drag the outgoing connector pin out and create a new node of type Sample Texture 2D. This node will allow us to sample the Texture2D variable and now work with that texture in our shader.
Now do that for the other three textures. Once you are done, you should have four texture variable nodes connected to four Sample Texture 2D nodes.
Step 5: Multiplying
Before we start connecting anything to the Master Stack, we are going to start creating our multipliers. The multipliers being the three floats we created. So similar to how we created the Sample Texture 2D nodes, we are going to bring in our Float variables and connect them to multiply nodes.
Add the rest of the variables an connect to the Multiply node. Your final result should look similar to the next image.
Step 6: Connecting to the Master Stack
The Master Stack has five nodes we need to connect to so that we can get a base PBR shader. Those nodes are the Base Color, Normal, Metallic, Smoothness, and Ambient Occlusion. Since the Metallic and Smoothness actually only take one channel, we are going to split the Roughness texture and send just a single channel of the texture out.
The Albedo and Normal textures will be the easiest to connect. We can just connect directly from the Sample Texture 2D nodes for both of them.
The next step is going to connect the Metallic and Smoothness nodes in the Master Stack to the outputs of the Multiply nodes. The input of those multiply nodes will be the Red and Green channels of the Roughness texture’s Sample Texture 2D nodes.
Because the Roughness texture is black and white, the Red, Green and Blue channels will all be the same value.
For the last node in the Master Stack that we are going to fill, Ambient Occlusion, we are going to do the same as the Metallic and Smoothness but instead of just the single channel, we are going to send all the channels to the Multiply node. Then we can finish up by connecting the output of that Multiply node to the Master Stack’s Ambient Occlusion node.
The final shader for a basic PBR shader should look like the following image.
Wrap up
That’s all the steps you need to create a basic PBR shader. With the right textures, this basic shader can make 2d surfaces look incredibly realistic.
For this and more Shader Graph tutorials check out my whole Unity Shader Graph series.
The Author
I’m a self taught Software Engineer specializing in Unity development. I’m also the lead engineer on SeeSignal, the world’s first XR application that allows users to see radio frequencies around them in real-time. SeeSignal is currently used by Telia, a telecom company owned by the Swedish government, to help their field technicians diagnose wireless connectivity issues for their residential and commercial clients.
Buy me a Ko-Fi/MikeQ or check out my Solutions for Sale!