Vertex Colors as Splat Map for Terrain Texture colors blown out

Hi All,

I am writing a custom surface shader to use the RGB channels of a mesh’s Vertex Colors to be used as a splat map for a terrain mesh. So far the shader “works” except where this is a color blended in 2 or more color channels.

I have attached the code, the image of the result inside of Unity, and the result inside of Blender using Vertex Colors as the splat map. As you can see, where there is both a R, and a G channel in the vertex colors, the texture blending gets blown out, yellow and not the grass texture" of a pure green vertex color.

Any help is greatly appreciated:

Shader "Vertex Color Splat Surf Shader" {
    Properties {
        _Splat1 ("Base (RGB)", 2D) = "white" {}
        _Splat2 ("Base (RGB)", 2D) = "white" {}
        _Splat3 ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Transparent" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf BlinnPhong
        
        sampler2D _Splat1;
        sampler2D _Splat2;
        sampler2D _Splat3;
 
        struct Input {
            float2 uv_Splat1;
            float2 uv_Splat2;
            float2 uv_Splat3;
            float4 color: Color; // Vertex color
        };

        void surf (Input IN, inout SurfaceOutput o) {
            half4 splat1 = tex2D (_Splat1, IN.uv_Splat1);
            half4 splat2 = tex2D (_Splat2, IN.uv_Splat2);
            half4 splat3 = tex2D (_Splat3, IN.uv_Splat3);
            half4 vc = normalize(IN.color);
            o.Albedo = splat1.rgb * vc.r; // vertex RGB
            o.Albedo += splat2.rgb * vc.g;
            o.Albedo += splat3.rgb * vc.b;
            o.Albedo = saturate(o.Albedo);
            o.Alpha = vc.a;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

Unity Blown Out Colors
Unity Blown Out Colors

Blender Correct Version
Blender Correct Colors

Anyone wondering about a fix for this problem, it was the blending equation. Blending based on multiplication caused the blow out. Instead, I had to lerp between each channel in the vertex color map.

The code is below:

Shader "Vertex Color Splat Surf Shader" {
    Properties {
        _Splat1 ("Base (RGB)", 2D) = "white" {}
        _Splat2 ("Base (RGB)", 2D) = "white" {}
        _Splat3 ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Transparent" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf BlinnPhong
        
        sampler2D _Splat1;
        sampler2D _Splat2;
        sampler2D _Splat3;
 
        struct Input {
            float2 uv_Splat1;
            float2 uv_Splat2;
            float2 uv_Splat3;
            float4 color: Color; // Vertex color
        };

        void surf (Input IN, inout SurfaceOutput o) {
            half4 splat1 = tex2D (_Splat1, IN.uv_Splat1);
            half4 splat2 = tex2D (_Splat2, IN.uv_Splat2);
            half4 splat3 = tex2D (_Splat3, IN.uv_Splat3);
            fixed3 albedo = lerp(splat1.rgb, splat2.rgb, IN.color.g);
            albedo = lerp(albedo, splat3.rgb, IN.color.b);
            
            o.Albedo = albedo;

        }
        ENDCG
    } 
    FallBack "Diffuse"
}

Now there is a much nicer look and feel here:
alt text