Simple progress bar shader - TUTORIAL (Patreon)
Content
Here is a first shader tutorial here!
PS: It's implied that you already have Amplify Shader Editor and know how to work with it's GUI and create a shader files, at least.
The first that you should know about shaders, all that happens in it's logic is just a math. Even visual stuff with textures is math. Sometimes it's really complex, but, for now, it will be simple.
How to create your own progress bar without any textures, just generated with code? It's easier than you think.
First of all, let's set our shader model as Unlit:
This means that we are going to use only Emission shader parameter and lights will not affect the result. This step isn't necessary, but it will be enough for this kind of shader.
First of all, let's just draw a linear gradient instead of a progress bar. To draw it in object's UV space, you can use a "Texture Coordinates" node ("U" key).
You can preview any node output with a "Relay" node, so let's see what a "Texture Coordinates" node outputs:
So, "U" outputs a horizontal gradient, which is actually an X UV position.
And "V" outputs a vertical gradient, which is actually a Y UV position.
NOTE: Output is represented in UV space.
Now let's connect a U output to the "Emission" shader input and compile the shader to check how it looks like in game. I'm using a quad mesh for this demonstration:
Black color represents 0 value and White represents 1. Yes, let's look on it like this, cuz it's just a math, as I said before.
NOTE: This gradient doesn't looks like a proper linear gradient because of the linear color space I use in my Unity projects. Read more about it here: https://docs.unity3d.com/Manual/LinearRendering-LinearOrGammaWorkflow.html
So, now there are a lot of ways to turn this gradient into a progress bar.
The most logical way is just to compare the gradient value to a progress bar percentage value. Let's draw 0 (Black color) if the progress bar value higher then the gradient value and draw 1 (White color) in other cases.
That's how it looks like using nodes:
We can also use colors instead of 1 and 0 values to make it more fabulous:
Actually, it's done! But, as I said, there are more ways to make it. "If" node is almost never the best solution, so let's use just math functions to get the same result.
Obviously, our values can be higher or lower then 1 and 0. So lest's just use this "feature" and the "Sign" node. The "Sign" node converts every input value to c values depending on the input value's sign. Basically, that's a representation how it works:
So, that's a progress bar logic with a "Sign" node:
What's happening here is just a simple subtraction. We're subtracting our gradient value from our progress bar value. Visually it shifts the gradient to the left. Then, when we apply a "Sign" node, it outputs -1, 0 or 1 instead of the smooth gradient color. But! -1 isn't a correct value to use in a future operations, so let's clamp it with a "Saturate node". Visually it does nothing for now, but actually it clamps the output value between 0 and 1:
But who said that even this is the best solution? This isn't even my final form!
Here's a solution with the "Ceil" node:
What the "Ceil" node does? It rounds your float value up to the integer value. That's a representation:
Why is this better then the previous solution? It doesn't requires a "Saturate" node, that's why. It already outputs the right values if your progress bar value is in [0;1] range.
And finally, how to colorize it all? There are still lots of ways!
A way of using simple arithmetic operations for coloring:
And a way of using a "Lerp" node, which is a much more clear way:
And what the "Lerp" node does? It just mixes A and B inputs using Alpha input mask. That's a better representation with a gradient Alpha input:
So, that's it! Hope, it was pretty much understandable. And remember, there are always hundreds of ways to do a thing, just try to find the best way :3