
Gradient Mapping Character Shader
Created a gradient mapping shader for stylized character rendering with team color support
Context
This is an overview of the shader that I created for the art team of Rift Wars. At the time of creation, the game's character shader used a color tinting method to give enemy units a red tint. This blending method resulted in heavily limited, washed out, and monotone results.

What is Gradient Mapping?
Gradient mapping is a powerful shader technique used in game development to remap the grayscale values of a texture to a custom gradient of colors. This method involves converting an original texture to grayscale and then applying a color gradient to it using a shader. In tools like Unity's Shader Graph, this is achieved using the 'Sample Gradient' node, which allows developers to define a custom gradient that replaces the grayscale values with new colors.

How Does Gradient Mapping Work?
- Grayscale Conversion: The original texture is converted to grayscale, where each pixel's intensity ranges from black (0% intensity) to white (100% intensity).
- Gradient Sampling: The shader uses these grayscale values as keys to sample a custom gradient. For instance, a pixel with a 50% grayscale value would sample the color at the midpoint of the gradient.
- Color Replacement: The sampled colors from the gradient replace the original grayscale values, effectively recoloring the texture based on the defined gradient.
- Combining Vertex Colors with Gradient Mapping: The shader can use vertex color information as input for gradient sampling. This means that the vertex color can determine which gradient to use on various parts of the mesh. This is incredibly valuable for complex models that consist of different "materials" within the texture itself. For example, skin and clothes on the same texture can have two entirely separate gradients.


The Tricky Part
Shader Graph does not support the data type gradient by default. This means that it cannot be easily exposed in the inspector for artists to interact with.
Chroma: Easy Pro Shaders
https://assetstore.unity.com/packages/vfx/shaders/chroma-easy-pro-shaders-231313
Chroma does support gradients as a data type, and they can be exposed in the inspector. Unfortunately, this is accomplished through the generation of a texture for each gradient. Remember, a large part of our goal here is to reduce draw calls and memory overhead, and we are trying to apply up to three gradients on each asset. Those extra draw calls are not going to do us any favors.

Gradient Atlas
One alternative, which requires some custom tooling, is to author a gradient atlas. In this atlas, each row contains a 1-pixel-tall gradient. The limitation here is the resolution of the texture; use the smallest resolution possible to reduce file size and memory load.
The shader can then sample an index property to reference a specific row. This allows each vertex channel to use unique gradients.


The Filter Mode of the gradient atlas must be set to Point (no filter)
Performance
At the end of the day, we are trading some performance for agility. This technique is never going to outperform a standard unlit character shader as we are, at minimum, adding an additional texture to hold gradients and creating branching for each vertex color. Your results may vary based on target-device, but for me, the cost here has been more than acceptable for how much is gained.


Workflow Benefits
Gradient mapping offers several advantages. It allows for dynamic color customization, enabling artists and developers to adjust colors in real-time without the need for new textures. This flexibility accelerates the iteration process and facilitates rapid prototyping. Additionally, it ensures a consistent style and quality across different assets since the same gradient can be uniformly applied, enhancing the visual coherence of the game.
Managing a single grayscale texture per asset simplifies asset management, reducing potential errors and making the project easier to maintain.
Lastly, gradient mapping opens up creative possibilities for effects like dynamic color shifts, player-customizable colors, and thematic changes (e.g., day-night cycles) without requiring additional textures.
