Learning Foundations of Unity Shaders

January 18, 2019

Intro to Shaders in Unity

Glitchy Man Material

Unity3D - Live Training Session: Writing Your First Shader In Unity

This tutorial was pulled from the tutorial list I created January, 17th ("Assorted Unity Tutorials - Structs, Shaders, and Unity Architecture"). IT not only introduced me to the core components that make up a shader in Unity, it also covered a lot of terminology and behind the scenes information to give me a better foundational understanding of how shaders operate.

Types of shaders you can create in Unity:
  • Surface Shaders: code generation approach that’s easier to write lit shaders than using low level vertexe/pixel shader programs
  • Unlit Shaders: don’t interact with Unity lights, useful for special effects
  • Image Effect Shaders: typically postprocessing effect that reads source image, does calculations, and renders result
  • Compute Shaders: programs run on graphics card, outside normal rendering pipeline; used for massively parallel GPGPU algorithms or accelerate parts of games rendering
Explaining Basic Shader Script

Shaders go onto a material. Determines how a material is rendered. Standard for Unity shader uses Shader Language. The Properties block is similar to public variables in Unity, as they can be seen in editor. The Pass block is where script passes logic to renderer. Tags explain how it wants to be rendered. The two structs (data functions) pass into main functions. These are the vertex function (vert) and the fragment function (frag).

Core Terminology for Shader Scripts
  • Vertex Function: takes shape of model and potentially modifies it; gets the vertices of model ready to be rendered; converts form object space to clip space (relative to camera); result goes to fragment function
  • Fragment Function: applies color to shape output by vertex function; this paints in the pixels
  • Property Data: colors, textures, values set by user in inspector
  • LOD (Level of Detail): this goes with how detailed object is (usually associated with idea in games where closer objects have higher detail and far objects have low detail)

Shaders do not use inheritance. Most classes in Unity start as Monobehavior, which gives you a lot of nice base functions. Shaders need that included, which is what the line { #include “UnityCG.cginc”} is for. This includes the use of a bunch of helpful helper functions.

Two important structs: appdata and v2f. appdata passes in information of vertices of 3D model. These are passed in in a packed array (variable with 4 floating point numbers: x, y, z, w). POSITION is a semantic binding, this tells shader how something will be used in rendering. V2f is short for “vert to frag”.

Coordinate system translations:

Local space -> World Space -> View Space -> Clip Space -> Screen Space

Looking into fragment sections

Fixed4 can either be: x,y,z,w or for color, r,g,b,a. Created a variable _TintColor in properties, which showed up in Unity inspector under the Unlit_Hologram material. This then needed to be used in the CGPROGRAM to actually do anything. We added this color to the fixed4 col found in fixed4 frag, which “adds” the colors together.

Making a transparent Shader

First, changed RenderType in Tags from Opaque to Transparent. Also needed to add “Queue” = “Transparent” here, as the order things are rendered is also important. Because of this, you want other things rendered before rendering the transparent thing because you want the transparent thing rendered “on top”. There are several primary queue tags that exist for rendering order. The following is the order of rendering generally, from first to last.

Primary Queue Tags for Render Order:
  • Background (first, back)
  • Geometry (Default)
  • AlphaTest
  • Transparent
  • Overlay (last, top)

Add ZWrite Off keyword. Tells us to not render on the depth buffer. This is usually done for non-solid objects (i.e. Semi-Transparent).

Displacing vertices and clipping pixels

Using the function “clip” in frag function to clip out pixels within a certain threshold. Adding sin function along with several variables (Speed, Amplitude, Distance, Amount (Multiplicative Factor)) into vertex function to move vertices around in object space, relative to the object. This is done before passing into the frag function. _Amount was a factor in a range between 0 and 1 just to control how much the shader effect was happening. The amount was important for the C# script used to control the effect on a time based interval. The C# script, HoloManGlitcher, could access the variables within the shader script. This was done simply through the material. (i.e. holoRenderer.material.SetFloat (“_Amount”, 1f); )

Comments

Popular posts from this blog

Online Multiplayer Networking Solution Tutorial Using Unity and Mirror - Tutorial by: Jason Weimann

Sebastian Lague A* Tutorial Series - Path Smoothing - Pt. 08 and Pt. 09

Designing Pixel Art Color Palettes in Aseprite by AdamCYounis