LOG: SHADER MASTERY
We've been working more on crafting a more responsive world -- populated with assets that react to the presence of the Teller. We wanted to do this using shaders. We realized many of our shaders did things we want (movement, color shifting, masking, distortion...), but there wasn't one that handled it all. We already had too many shader variations and it was getting unwieldy.
Tackling this resulted in some fantastic re-working of the shader code/workflow, alongside an injection of life into our forest flora assets.
Breakdown: Building the Master Shaders
In this log, Jerry gives an overview of our new Unity 3D shader implementation.
Shaders have always been a bit of an undercooked feature in Unity. You have to write the code by hand, there’s no good syntax highlighting for it, it feels clumsy. And what about this: You have made a nice shader and an artist asks you “Hey, I need another tint color in that shader but I’m only going to need it for this one asset. Can you give me another shader with that tint color added? K Thanks!”.
After some muttered curses and a facepalm you have no choice but to reply “Sure.”.
You end up with another shader file, another slight variation. Perhaps that shader is now called “Character shader panning glow emissive masked normal boost extra tint” That’s just insane!
This exact situation has bothered me for years, especially since I’ve worked extensively with Unreal 3 and 4 where dealing with this is just a breeze.
In unreal there is the concept of a MaterialInstance, basically a shader with options. You want to enable the tint? Just check the checkbox and slap that color on there! Easy.
So now your shader can just be called “Character shader” and all those other things; panning, glow, emissive, normal boost etc. are options that can be turned on or off based on the needs of the artist. Makes sense.
Of course I would not be writing this If there wasn’t a way to do this in Unity so let’s dive right in! Fortunately, almost all of the hard work had already been done by others. Mainly Unity itself and Martin Palko.
First, lets look at Unity, in Unity 5 they introduced the Standard Shader. This shader has some dropdown options to change BlendMode and UV channel. So, not many options, but options nonetheless. That means it’s at least possible to achieve something like what we want.
Time for some further investigation. All the built-in shaders can be downloaded from the Unity site to see how they function. I don’t want to go to deep into the details of it but there are two main aspects to make this work:
1. The #pragma multi_compile shader preprocessor keyword.
2. Using a CustomEditor for the shader.
Martin Palko has taken these concepts and built a system out of it that’s quite similar to that of Unreal.
In essence this is the system I wanted. However I did add some features that I felt were missing. First, I added a way to show or hide togglegroups based on the state of another togglegroup.
I also integrated the concept from the Unity Standard Shader to be able to switch between different blend modes.The current blend mode can also determine if a property or togglegroup is visible or not.
1. I wanted to set the "IgnoreBatching" tag from code but this is currently broken.
2. I wanted to have a switch for using Stencil. I don't believe it's possible to have #if blocks outside the CGPROGRAM block so I don't think this can be done.
Still, it's pretty awesome and really speeds up the workflow.
Here's some of the resulting in-game work using Master Shaders to selectively combine different effects, such as vertex animation, color shifting, scaling, distortion, secondary add/multiply layer blending, and so on) :
If you have any questions, don't hesitate to ask.