Shaders (lg)

Learning goal on shaders.

Introduction to shaders

What are shaders?

Shaders are a special kind of program that run on a Graphics Processing Unit (GPU). Most computer have some sort of GPU either integrated into the CPU or a separate hardware component. GPU's are especially useful for rendering because they are optimized for tuning thousands of instructions in parallel.

There are a number of shader languages used in real-time rendering:

and other platform specific languages. A few examples are The experimental Webshading Language, PlayStation Shading Language (PSL), and older C for Graphics (Cg) used in the older Unity 3D code. (https://alain.xyz/blog/a-review-of-shader-languages#ref_maxfield2018)

Each shader contains 1 or more Subshaders. Subshaders let you define different GPU settings and shader programs for different hardware, render pipelines, and runtime settings. Some shader objects contain only a single Subshaders while others contain multiple Subshaders for supporting different configurations. Subshaders can contain one or multiple Passes.

A Pass is the fundamental element of a Shader object which contains instructions for setting the state of the GPU, and the shader programs that run on the GPU.(https://docs.unity3d.com/Manual/SL-Pass.html)

Different kinds of shaders

There are Vertex shaders and Fragment shaders.

Vertex shaders manipulate coordinates or a 3D space and are called once per vertex.

Fragment shaders (also known as texture shaders) define RGBA (red, green, blue, alpha) colors for each pixel being processed.

What are the possibilities for shaders?

The second is by using a plugin called Shader Graph. In able to use Shader Graph you must first have either the Universal Render Pipeline (URP) or the High Definition Render Pipeline (HDRP). This usually automatically installs Shader Graph with is. Once that's done you need to configure Unity to use either of these pipelines.

Which should I use?

In Unity it is possible to create shaders in a few ways. The first is manually writing a shader from script which can be completely customized to the needs of your project.

To be able to decide on which to use i first need to look at that the pro's and cons are of both possibilities.

SL-Pro'sSL-Con'sSG-Pro'sSG-Cons

Extremely customizable

Takes Longer to learn

Visual Scripting

Limited to what Shader graph do

Learn the inner workings of a shader

Run-time results

Another thing I need to take into consideration is what do we need to do with our current project to be able to implement shader graph. To be able to use shader graph we need to add either the Universal Render Pipeline (URP) or the High Definition Render Pipeline (HDRP) as seen earlier.

I decided it would be a good idea to first test both possibilities before making a decision.

Writing my first shaders

To start off I created a completely new testing project so I wouldn't destroy anything from our own project. Here I imported the Universal Render Pipeline and set it up to use this pipeline instead of the built in Unity pipeline. Once done I started with the basics of Shader Graph.

Shader Graph

I started watching tutorials about how to create shaders with Shader Graph. Brackeys was used for this first attempt. (https://www.youtube.com/watch?v=Ar9eIn4z6XE&ab_channel=Brackeys)

Now I have a basic understanding of what shaders are and how they can be used I decided it would be a good idea to take a look into Shader Lab and writing a custom shader.

Shader language

For our project we thought it would be a really good idea to implement some kind of echolocation visualizations. This would be a cool thing to work on as a shader.

I started off by searching for tutorials on echolocation shaders but unfortunately mostly only found Shader Graph tutorials in general. Custom written shader tutorials were harder to find. After a decent amount of time searching I came across a tutorial on how to make a ripple effect in Shader Lab.

With the tutorial I was able to make a sonar kind of effect. By giving this shader multiple parameters. A few of those were distance to travel, width and travel speed.

Now this was starting to look more like something we could use. I found that the color whit was a bit too heavy on the eyes, especially in VR so I decided to make it a bit more soothing. First I tried using pink but found it was still a bit too straining on the eyes.

So I decided to change it to another color and blue seemed to be about right.

Another parameter I used was the origin so I could adjust the position on the effect. The main reason for doing this was because in our project we have a mechanic where the player uses voice input to cause the ripple that creates vision for the player at their current position.

Now that I have my shader I want to test it in working.

First of all I tested this myself. One of the main problems was that the skybox was showing which meant the player was not 'blind'. By turning off the skybox rendering method and making it render a color that was black, I was able to fake that there was no sun.

the next problem was that this was a surface shader which showed lighting and we needed it to be very dark as if there was no light to make it feel as the player was blind.

Looking back

It might have been easier to make a shader graph shader to save on time as it took up almost all of sprint 2 to get it working with 1 ripple. Although seeing as how i wanted to learn more about the workings of shaders and how I would be able to program one without some kind of visual tool. I do however think that in the future i will look into shadergraph next time i want to create shaders just to increase productivity and seeing as there are way more references about shadergraph is could be easier to learn.

Last updated