Book Image

Unity 5.x Shaders and Effects Cookbook

By : Alan Zucconi
Book Image

Unity 5.x Shaders and Effects Cookbook

By: Alan Zucconi

Overview of this book

Since their introduction to Unity, Shaders have been notoriously difficult to understand and implement in games: complex mathematics have always stood in the way of creating your own Shaders and attaining that level of realism you crave. With Shaders, you can transform your game into a highly polished, refined product with Unity’s post-processing effects. Unity Shaders and Effects Cookbook is the first of its kind to bring you the secrets of creating Shaders for Unity3D—guiding you through the process of understanding vectors, how lighting is constructed with them, and also how textures are used to create complex effects without the heavy math. We’ll start with essential lighting and finishing up by creating stunning screen Effects just like those in high quality 3D and mobile games. You’ll discover techniques including normal mapping, image-based lighting, and how to animate your models inside a Shader. We’ll explore the secrets behind some of the most powerful techniques, such as physically based rendering! With Unity Shaders and Effects Cookbook, what seems like a dark art today will be second nature by tomorrow.
Table of Contents (16 chapters)
Unity 5.x Shaders and Effects Cookbook
Credits
About the Authors
www.PacktPub.com
Preface
Index

Creating a basic Standard Shader


Every Unity game developer should be familiar with the concept of components. All the objects that are part of a game contain a number of components that affect their look and behavior. While scripts determine how objects should behave, renderers decide how they should appear on the screen. Unity comes with several renderers, depending on the type of object that we are trying to visualise; every 3D model typically has MeshRenderer. An object should have only one renderer, but the renderer itself can contain several materials. Each material is a wrapper for a single shader, the final ring in the food chain of 3D graphics. The relationships between these components can be seen in the following diagram:

Understanding the difference between these components is essential to understand how shaders work.

Getting ready

To get started with this recipe, you will need to have Unity 5 running and must have created a new project. There will also be a Unity project included with this cookbook, so you can use that one as well and simply add your own custom shaders to it as you step through each recipe. With this completed, you are now ready to step into the wonderful world of real-time shading!

How to do it…

Before getting into our first shader, let's create a small scene for us to work with. This can be done by navigating to GameObject | Create Empty in the Unity editor. From here, you can create a plane to act as a ground, a couple of spheres to which we will apply our shader, and a directional light to give the scene some light. With our scene generated, we can move on to the shader writing steps:

  1. In the Project tab in your Unity editor, right-click on the Assets folder and select Create | Folder.

    Note

    If you are using the Unity project that came with the cookbook, you can skip to step 4.

  2. Rename the folder that you created to Shaders by right-clicking on it and selecting Rename from the drop-down list or selecting the folder and hitting F2 on the keyboard.

  3. Create another folder and rename it to Materials.

  4. Right-click on the Shaders folder and select Create | Shader. Then right-click on the Materials folder and select Create | Material.

  5. Rename both the shader and material to StandardDiffuse.

  6. Launch the StandardDiffuse shader in MonoDevelop (the default script editor for Unity) by double-clicking on it. This will automatically launch the editor for you and display the shader code.

    Note

    You will see that Unity has already populated our shader with some basic code. This, by default, will get you a basic Diffuse shader that accepts one texture. We will be modifying this base code so that you can learn how to quickly start developing your own custom shaders.

  7. Now let's give our shader a custom folder from which it's selected. The very first line of code in the shader is the custom description that we have to give the shader so that Unity can make it available in the shader drop-down list when assigning to materials. We have renamed our path to Shader "CookbookShaders/StandardDiffuse", but you can name it to whatever you want and rename it at any time. So don't worry about any dependencies at this point. Save the shader in MonoDevelop and return to the Unity editor. Unity will automatically compile the shader when it recognizes that the file has been updated. This is what your shader should look like at this point:

    Shader "CookbookShaders/StandardDiffuse" {
      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
      }
      SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows
    
        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0
    
        sampler2D _MainTex;
    
        struct Input {
          float2 uv_MainTex;
        };
    
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
    
        void surf (Input IN, inout SurfaceOutputStandard o) {
          // Albedo comes from a texture tinted by color
          fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
          o.Albedo = c.rgb;
          // Metallic and smoothness come from slider variables
          o.Metallic = _Metallic;
          o.Smoothness = _Glossiness;
          o.Alpha = c.a;
        }
        ENDCG
      } 
      FallBack "Diffuse"
    }
  8. Technically speaking, this is a Surface Shader based on physically-based rendering, which Unity 5 has adopted as its new standard. As the name suggests, this type of shader achieves realism by simulating how light physically behaves when hitting objects. If you are using a previous version of Unity (such as Unity 4), your code will look very different. Prior to the introduction of physically-based shaders, Unity 4 used less sophisticated techniques. All these different types of shader will be further explored in the next chapters of this book.

  9. After your shader is created, we need to connect it to a material. Select the material called StandardDiffuse that we created in step 4 and look at the Inspector tab. From the Shader drop-down list, select CookbookShaders | StandardDiffuse. (Your shader path might be different if you chose to use a different path name.) This will assign your shader to your material and make it ready for you to assign to an object.

    Note

    To assign a material to an object, you can simply click and drag your material from the Project tab to the object in your scene. You can also drag a material on to the Inspector tab of an object in the Unity editor to assign a material.

The screenshot of an example is as follows:

Not much to look at at this point, but our shader development environment is set up and we can now start to modify the shader to suit our needs.

How it works…

Unity has made the task of getting your shader environment up and running, which is very easy for you. It is simply a matter of a few clicks and you are good to go. There are a lot of elements working in the background with regard to the Surface Shader itself. Unity has taken the Cg shader language and made it more efficient to write by doing a lot of the heavy Cg code lifting for you. The Surface Shader language is a more component-based way of writing shaders. Tasks such as processing your own texture coordinates and transformation matrices have already been done for you, so you don't have to start from scratch any more. In the past, we would have to start a new shader and rewrite a lot of code over and over again. As you gain more experience with Surface Shaders, you will naturally want to explore more of the underlying functions of the Cg language and how Unity is processing all of the low-level graphics processing unit (GPU) tasks for you.

Note

All the files in a Unity project are referenced independently from the folder that they are in. We can move shaders and materials from within the editor without the risk of breaking any connection. Files, however, should never be moved from outside the editor as Unity will not be able to update their references.

So, by simply changing the shader's path name to a name of our choice, we have got our basic Diffuse shader working in the Unity environment, with lights and shadows and all that by just changing one line of code!

See also

The source code of the built-in shaders is typically hidden in Unity 5. You cannot open this from the editor like you do with your own shaders.

For more information on where to find a large portion of the built-in Cg functions for Unity, go to your Unity install directory and navigate to Unity45\Editor\Data\CGIncludes. In this folder, you can find the source code of the shaders shipped with Unity. Over time, they have changed a lot; UNITY DOWNLOAD ARCHIVE (https://unity3d.com/get-unity/download/archive) is the place to go if you need to access the source codes of a shader used in a different version of Unity. After choosing the right version, select Built in shaders from the drop-down list, as shown in the following image. There are three files that are of note at this point—UnityCG.cginc, Lighting.cginc, and UnityShaderVariables.cginc. Our current shader is making use of all these files at the moment:

Chapter 10, Advanced Shading Techniques, will explore in-depth how to use GcInclude for a modular approach to shader coding.