2 Tone Hair Shader
Key Problem
UploadFinding Inthe Progressbest practice on how to blend 2 color for hair. The common practice in blending color usually done with alpha channel, but since alpha channel will be used for hair transparency / alpha testing, it can not be used.
Possible Solutions
If hair color is uniform
If the hair color is uniform, the hair texture grayscale can be assigned to one of the rgb channel, and the blending map to another channel. For example the texture grayscale assigned to red channel and blend map to green channel
And here’s the shader that can be used to blend the hair colors/tones
Shader "Custom/Hair"
{
Properties
{
_HairTex ("Hair Tex", 2D) = "white" {}
_HairNormal ("Hair Normal", 2D) = "bump" {}
_Color ("Hair Color 1", Color) = (1,1,1,1)
_Color2 ("Hair Color 2", Color) = (1,1,1,1)
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_Glossiness ("Smoothness", Range(0.001,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows alphatest:_Cutoff
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _HairTex;
sampler2D _HairNormal;
struct Input
{
float2 uv_HairTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
fixed4 _Color2;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Color is lerped using texture's green channel between HairColor1 and HairColor2
// Albedo comes from a texture's red channel tinted by lerped Color
fixed4 baseColor = tex2D (_HairTex, IN.uv_HairTex);
fixed3 color = lerp(_Color2, _Color, baseColor.g).rgb;
fixed3 hairColor = baseColor.r * color;
fixed3 hairNormal = UnpackNormal(tex2D (_HairNormal, IN.uv_HairTex));
o.Albedo = hairColor.rgb;
o.Normal = hairNormal;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = baseColor.a;
}
ENDCG
}
FallBack "Diffuse"
}
Blend using uv map position
Blending Hair tones can also be achieved by using uv map position, but this requires the model to be uv mapped in specific mapping
The shader is almost the same with above, but instead of using texture’s blue channel, we use uv position (in this example, y)
// Color is lerped using uv.y position between HairColor1 and HairColor2
// Albedo comes from a texture's red channel tinted by lerped Color
fixed3 color = lerp(_Color2, _Color, IN.uv_HairTex.y).rgb;