Search Unity

In 2018.1 we introduced a new tool called Shader Graph which allows you to build shaders visually.  We have added a lot of exciting new features recently. Download Unity 2018.2 and our new demo project to explore them!

Some of the features that are new to Shader Graph in 2018.2 include:

  • High Definition Render Pipeline (HDRP) support
  • Vertex Position
  • Property Reference Names
  • Editable Paths for Graphs
  • New nodes: gradients, texture 2D array, texture 3D, and more!

Using the Demo Project

Let’s dive into our sample project and take a look at how to use ShaderGraph to create foliage based scenes. First, download the sample project here. If you’re unfamiliar with GitHub, you can download a ZIP archive of the project.

Much like our new template projects, this project has a Readme for quick reference to documentation about the tools we use.

The project comes with sample graphs for great looking foliage and environment shaders and also demos a technique for switching between two render pipelines. On the Readme inspector, you’ll find buttons to switch between Lightweight and High Definition Render Pipelines. This is mainly to allow you to author assets and test compatibility between pipelines — for production, we recommend using only one render pipeline.

Find the sample scene in the Assets > Scenes folder to get started. The next few sections will review some of the graphs you’ll see in this demo project!

Standard Shader Graph

Do you find the standard surface shaders in Unity helpful? Well, good news! You can make your own using the Shader Graph! You can find our example graph in the Assets/Shaders/ folder of the demo project.

The properties of our graph are almost the same as the options you’d find on the standard surface shaders. Our graph follows the packed texture format for Mask maps from the HDRP. Since this is a graph, you can customize this to suit your project’s needs.

There are some unique qualities in this project’s standard shader, including:

  • Two-Sided rendering enabled in the Master Node settings
  • Our new Is Front-Face node to flip back-facing normals
  • A world-position based dither mask in the alpha channel

Simple Vegetation Graph

You’ll also find a simple vegetation graph in this project. This graph is a standard shader with simple vertex animation. It produces a very simple sway back and forth with a bit of turbulence added on for variation.

We control the animation with vertex colors. For basic animation, we use a simple gradient from black to red so only the ends of the foliage animate while the base stays rooted in the ground. More complex animations will need more complex colors.

The basis for any good foliage animation is a wave. This graph uses a sine wave with time input and remapped values for visual appeal. The black line represents a basic sine wave, and the red line represents our remapped sine wave.

The turbulence wave is a modified version of the basic sine wave. It varies the speed of the wave rather than the amplitude. This gives a random flickering value, which we can use to create some small fluttering on top of our base wave. Here we’ve added a blue line to show the difference between our standard sine wave and the turbulence wave.

We add the two waves together and multiply by the desired vertex color, the red painting we saw on our plant above. Then, we add our wave to our object position to create the vertex offset. Here we’re only creating an offset in the X-axis, but this is useful for any direction or all axes at once. Take the final output and plug it into the Position slot on the Master node, and we’ve got a nice simple animation for foliage to wave in the wind.

Complex Vegetation Graph

We have also included a complex vegetation graph in this project. The motion is based on a great paper by Tiago Sousa, found in Nvidia’s GPU Gems 3. The paper has a wonderful breakdown of the math behind the system, so we’re going to give a brief overview of the application.

This kind of system is best for larger foliage, like trees. It accounts for a large wave motion as the whole tree sways in the wind, smaller variation on the branches, and even smaller flutters for the leaves. The vertex colors applied to the mesh control the phases. The red determines what parts of the mesh should have smaller fluttering on the leaves, so it’s best for the edges of the leaf cards. The green adds timing variation, to make sure that the branches aren’t all waving at the same time. The blue determines where the branch attaches to the trunk, and what parts are most affected by the wind. This is a simple black-blue gradient from the base outwards.

When you combine these phases, you get a very nice feeling of wind blowing through the air.

When you look at the graph, however, you get a very nice feeling of… well, you get a feeling. Luckily, it’s not as complicated as it looks. Let’s break it down into smaller networks – a trunk phase, a branch phase, and a leaf phase!

This is the base trunk phase of our system. It starts with the same nodes as the turbulence that’s used in our simple vegetation graph. We multiply the wave by a direction property for finer control over where the wind is blowing. This also uses a remapped sine wave with variation, like the simple vegetation graph. Then, we add the turbulence and base wave together.

This section is our second phase — the branch sway. First, we isolate the movement of the trunk phase into a single vector value. We multiply the wave and blue vertex color channel to determine what parts of the mesh qualify as “branches”. Then we lower the intensity of the wave and make it faster. This creates a series of much smaller fluttering waves based off of the larger movement. The second half of our branch sway smooths out the values into a softer gradient. Not too bad!

This is the leaf phase of our animation, to add fast and fluttering movements. We start by using the red and green channels of the mesh vertex color to determine which edges should flutter rapidly. The green channel determines variation in the movement. Areas with higher green values will have more intense movement than areas with a lower green value. The red channel determines which parts of the mesh get intense fluttering movement. Usually, this works for the edges of the leaf cards on a tree mesh.

All that’s left now is to add everything together! Add the leaf phase to the branch phase, and that result to the main trunk phase, and we’ve got a nice complex wind effect!

If you want to know more about what we’ve done in this project, click through the example content in the Assets folder! Some of the scripts have an additional ReadMe file to get you started for your own projects.

If you want to take a look at more example content for Shader Graph, check out Andy Touch’s Shader Graph Example Library!

If you want to talk to us about the Shader Graph, check out the forums and stay tuned to the blog for more exciting updates!

22 코멘트

코멘트 구독

댓글 남기기

사용할 수 있는 HTML 태그 및 속성: <a href=""> <b> <code> <pre>

  1. Shader Graph is awesome. Will you guys add Vertex ID support? For now, it seems it is not possible to distinguish between different vertices.

  2. This looks a very interesting article – I’ll need to sit down and take time looking into this – Thanks very much!

  3. Thanks for this article, I made a good shader for vegetation, and created my nodes, including SSS.
    https://forum.unity.com/threads/nodes-for-shader-graph.543519/#post-3584384

    1. Amazing Job Andrey!

  4. There needs to be a way to visually group nodes together (not resulting in shader code at the end.) And you need to be able to add comments. Bigger graphs can get quite messy and you totally get lost without any commenting feature.

    1. Hey Maik,

      You can create subshaders which you can use to group nodes together and if you don’t use them simply not reference them. For the comments, I agree and that is something coming.

      1. I’ve tried using a subgraph, but ran into a problem that I couldn’t work around. Mainly, the subgraph returns basically a Vector4, but the Position port on the PBR master node expects a Vector3. I wasn’t able to connect both together. Then I tried splitting the Vector4 into its subcomponents, then combining RGB together into a new Vector3, and still the Position port wouldn’t accept the connection (it would grey out when dragging the edge.) I don’t have a clue why.

      2. Also, it looks like subgraphs can only return exactly one data type, which is quite cumbersome. I don’t want to deal with a Vector4 if my subgraph returns a Vector3. It doesn’t make sense.

  5. Wait, hold up. Where is that translucent effect came from? i don’t think you can change HDRP surface type in shadergraph yet??!!!

  6. Is there any way to write all that in code in the same/similar way as with surface shaders?
    I really find shader graphs too much overcomplicated and hard to follow. Many parts of those huge graphs could be put in a couple of lines in code.

  7. Thanks for delivering a tutorial about how to switch between renderpipelines.
    But in my opinion it needs too many steps/scripts/assets/prefabs/profiles etc. and should be much more userfriendly.
    Hopefully this will change when coming out of beta…..

  8. How to use the SSS Profile into a Shader Graph? I think we need that support asap.

  9. @Tufan Aydin

    That should just be a rim shader, I don’t see why shader graph couldn’t make that as it’s pretty standard.

  10. Amazing post, Alex! As somebody who’s experimenting a lot with ShaderGraph and trying to use it to the next level, this kind of advanced info is great. Thanks for the tips!

  11. For artists who don’t know how to start to build shaders visually, (since ShaderGraph is new), I recommend looking for “UDK shader” on Youtube.

  12. Thanks for the examples, it will be handy for artists like me who don’t know how to start doing their own modification of a standard shader.

  13. Please answer me. Can Shader Graph do now Toon shader with Outline? Can we make Outline shader like in cartoons?

    1. Yes, you can get that effect. See this example, the Rim effect can be a good starting point.

  14. nice! great post!