- Home /
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
Blender Correct Version
Answer by tpennetta · Mar 03, 2014 at 07:33 PM
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:
Hey tpennetta! I was really excited to find this. I am working on getting a custom mesh from Blender into Unity to use as my terrain and I am trying to solve how I am going to make a splat map that I can use in Unity. I really appreciate you posting the shader code but I was hoping you could elaborate more on the workflow you used to go from painting vertex colors on your model in Blender, to getting different textures to appear on the model in Blender from the vertex color information, to getting the model in Unity and getting the splat map setup using your shader. Thanks in advance for your time and help. Bryson