Introducing Shader Graph’s new Master Stack
In Unity 2020.2, we introduced several new features in Shader Graph that improved the workflow for artists. For example, by refining the user experience overall and introducing the Graph Inspector, Graph Editor performance has been greatly improved. As the end point of the Graph, the Master Stack is now a modular collection of feature blocks, replacing the monolithic Master Node.
The Master Stack is the end point of a Shader Graph that defines the final surface appearance of a shader. It helps users visualize the relationship between operations that take place in the vertex stage and the fragment stage. With Unity 2020.2, the Master Stack replaces the Master Node of earlier Unity versions.
The Graph Inspector consolidates the settings from the Master Node and other nodes within the graph into a single location. This is where you can set the active Target and the shading mode.
You can learn about all the new Shader Graph updates in this video overview.
Getting started with the new sample project
To help you get started using the new Master Stack feature, we have created a sample project that you can download from GitHub. Next, we will walk you through the sample project to show you a few examples.
To get started, clone or download the sample project.
This sample project was created using Unity’s Universal Render Pipeline (URP). The project includes a miniature beach environment featuring two different kinds of water built with shaders created in Shader Graph: the waterfall over the cliffs, and the ocean connected to the island. You can find the completed sample scene in Asset > Scenes > MasterStackDemoScene.
Now let’s take a closer look at how you can build up the water shaders using the new Master Stack feature.
Building the waterfall
For the waterfall shader, you only need to configure the base color channel and the alpha channel of the shader. You can offset and tile the UV of the waterfall model while using a Voronoi Node to generate texture. By using two One Minus Nodes to mask out the edges of the mesh in the alpha channel, the waterfall looks more natural.
Building the ocean
Before adjusting the actual graph, you need to think about the basic attributes you want the water shader to have. First of all, consider the color of the water. Then, elements like waves and tides make the water look vivid. The reflection of the water is also very important. Don’t forget to add some foam where the water reaches the shoreline. Last but not least, it will be great if the water has depth, because part of it is pretty close to the shoreline.
Now that you’ve determined the attributes of the water shader, let’s take a look at the sample shader to see how to achieve the intended result.
First, apply colors to the underneath glass bowl. The water shader uses four color properties. Two of them control the overall gradient, the other two are responsible for the deep and shallow water. The transition between deep water and shallow water is controlled by a depth value, which we will talk more about later.
Next, let’s review how the sample shader makes use of vertex displacement to represent tides. The new Master Stack displays the Vertex and Fragment shader separately, which makes it clear which nodes affect the vertices and simplifies the process of updating the graph.
In this section of the Shader Graph, the vertices are displaced over the y-axis. You can control the displacement strength and frequency with properties. You can use a Gradient Noise Node to add more variations to the tide frequency.
To achieve the visual result of small waves in the water, tile two normal maps in opposite directions with the tiling speeds controlled by time.
Now let’s take a look at how to represent the water reflections and depth.
Reflections on the water can be represented by applying smoothness to the shader. As always, there are two values, one for the top and one for the side of the glass bowl.
Before using the shader to create depth, make sure that the Depth Texture option is selected on the render asset you are using in the project. You can find the Depth Texture option in the General section on the render pipeline asset that you are using. The current render pipeline asset you are using is accessible via Edit > Project Setting > Graphics > Scriptable Render Pipeline Asset.
After making sure the Depth Texture is enabled, you can continue to add depth to the water shader.
You can calculate the depth of the water using the Scene Depth Node, the Screen Position Node and the camera’s far plane distance. There are also several depth properties set up on the blackboard so the water depth can be controlled from the material inspector. Then you can use the depth value with the Lerp Node to interpolate the colors of the deep and shallow water together.
Besides the deep water color and shallow water color, the water’s foam also depends on the depth value. However, in this case, the depth value needs to be inverted because the foam should only appear when the water intersects with something. The One Minus Node helps do that.
Now we have gone through all the key attributes! Feel free to explore and make your own adjustments in the project.
Note that shader graphs made in previous versions will be upgraded to use the Master Stack once you open them in the Graph Editor if the Shader Graph version is 10.0 or higher. We have also released an Upgrade Guide to provide more detailed instructions about how to upgrade your project to newer versions.
About the author
Siyu (Tracy) Chen (Technical Artist, R&D, Graphics) is a technical artist who is passionate about shader creation, tool development, and Look Dev. She was previously a Technical Artist intern at Unity and recently returned after graduating from the Entertainment Technology Center, Carnegie Mellon University.
She has worked on projects on different platforms, including various AR/VR devices and consoles.
She is currently working alongside engineers and designers whose mission is to make Shader Graph a user-friendly tool with increased stability and extensibility for faster workflow iterations.