Custom Terrain Engine - Shader issues

I have created my own Procedurally Generated Paging Terrain Engine. I create splat maps during the page creation process and I’ve been trying to use the default Terrain Shader that comes with Unity to texture the terrain. Each of my Splat maps use all 4 channels RGB and A. The Splat maps are the exact same width and height in pixels as the terrain page. So for a 64 unit by 64 unit Terrain page the Splat Maps are 64x64 pixels.

When the material is applied it uses the splat map multiple times over the page. I can’t seem to figure out why it’s doing that. The only thing I can think of is that the shader used by the Unity Terrain is not actually a Splat Shader so I’ve looked for other shaders that would do what I want and I have been unable to find any that work. Not knowing a whole lot about shader programming I’ve been stuck with terrain textured using a custom shader that just gave it a simple RGB color based on the height.

If any one could point me in the right direction I’d greatly appreciate it!

Here’s my Custom Shader that I’ve been using:

Shader "Terrain/CustomTerrain" {
	Properties {
		_Color1 ("Water Color", Color) = (1,1,1,1)
		_Color1Start ("Water Start", Range (0,600)) = 0 // sliders
		_Color2 ("Beach Color", Color) = (1,1,1,1)
		_Color2Start ("Beach Start", Range (0,600)) = 0 // sliders
		_Color3 ("Grass Color", Color) = (1,1,1,1)
		_Color3Start ("Grass Start", Range (0,600)) = 0 // sliders
		_Color4 ("Dirt Color", Color) = (1,1,1,1)
		_Color4Start ("Dirt Start", Range (0,600)) = 0 // sliders
		_Color5 ("Rock Color", Color) = (1,1,1,1)
		_Color5Start ("Rock Start", Range (0,600)) = 0 // sliders
		_Color6 ("Snow Color", Color) = (1,1,1,1)
	}
   SubShader {
      Pass {
         CGPROGRAM
 
         #pragma vertex vert  
         #pragma fragment frag 
		 #include "UnityCG.cginc"

		 float4 _Color1;
		 float _Color1Start;
		 float4 _Color2;
		 float _Color2Start;
		 float4 _Color3;
		 float _Color3Start;
		 float4 _Color4;
		 float _Color4Start;
		 float4 _Color5;
		 float _Color5Start;
		 float4 _Color6;
		 
         // uniform float4x4 _Object2World; 
            // automatic definition of a Unity-specific uniform parameter
 
         struct vertexInput {
            float4 vertex : POSITION;
         };
         struct vertexOutput {
            float4 pos : SV_POSITION;
            float4 position_in_world_space : TEXCOORD0;
         };
 
         vertexOutput vert(vertexInput input) 
         {
            vertexOutput output; 
 
            output.pos =  mul(UNITY_MATRIX_MVP, input.vertex);
            output.position_in_world_space = 
               mul(_Object2World, input.vertex);
               // transformation of input.vertex from object 
               // coordinates to world coordinates;
            return output;
         }
 
         float4 frag(vertexOutput input) : COLOR 
         {
             float dist = distance(input.position_in_world_space, 
               float4(0.0, 0.0, 0.0, 1.0));
               // computes the distance between the fragment position 
               // and the origin (the 4th coordinate should always be 
               // 1 for points).
 
            if (input.position_in_world_space.y <= _Color1Start)
            {
               return _Color1; 
                  // color near origin
            }
			else if (input.position_in_world_space.y <= _Color2Start  input.position_in_world_space.y >= _Color1Start)
            {
               return _Color2; 
                  // color near origin
            }
			else if (input.position_in_world_space.y <= _Color3Start  input.position_in_world_space.y >= 0)
            {
               return _Color3; 
                  // color near origin
            }
			else if (input.position_in_world_space.y <= _Color4Start  input.position_in_world_space.y >= 0)
            {
               return _Color4; 
                  // color near origin
            }
			else if (input.position_in_world_space.y <= _Color5Start  input.position_in_world_space.y >= 0)
            {
               return _Color5; 
                  // color near origin
            }
            else
            {
               return _Color6; 
                  // color far from origin
            }
         }
 
         ENDCG  
      }
   }
}

This one works,
“shader RGB colour based on y-value vertex”

My Custom Shader works just fine for displaying colors based on Height. I now want to use something for Splat Shader that will use actual Diffuse Textures based on the Splat Maps I generate.

Here’s an example of what the above shader generates:

The Blue is water, Orange is a Sandy Beach, and green would be grass. Now I want a shader that I can use the generated Splat maps to actually display a water texture, a Sandy beach Texture, and a Grass texture.

this is modified version of that shaders in answers,
i’m sure it could be simpler, but it worked for me… i think you can get some ideas from it:

used it here before (see main image)

// http://answers.unity3d.com/questions/54313/shader-rgb-colour-based-on-y-value-vertex.html

Shader "Custom/Global-Mapper-Textured"
{
Properties {
    _PeakLevel ("PeakLevel", Float) = 50
    _PeakTex ("Peak (RGB)", 2D) = "white" {}
	
    _RockLevel ("RockLevel", Float) = 30
    _RockTex ("Rock (RGB)", 2D) = "white" {}
	
    _GrassLevel ("GrassLevel", Float) = 20
    _GrassTex ("Grass (RGB)", 2D) = "white" {}
	
    _SandLevel ("SandLevel", Float) = 10
    _SandTex ("Sand (RGB)", 2D) = "white" {}
	
    _WaterLevel ("WaterLevel", Float) = 0
    _WaterTex ("Water (RGB)", 2D) = "white" {}
	
    _Slope ("Slope Fader", Range (0,1)) = 0
}
SubShader {
    Tags { "RenderType" = "Opaque" }
    //Fog { Mode Off }
    Tags { "LightMode" = "Always" }
    CGPROGRAM
	#pragma target 3.0
    #pragma surface surf Lambert vertex:vert

	sampler2D _WaterTex;
	sampler2D _SandTex;
	sampler2D _GrassTex;
	sampler2D _RockTex;
	sampler2D _PeakTex;

    struct Input {
		float2  uv_WaterTex;
        float3 customColor;
        float3 worldPos;
    };
	
    void vert (inout appdata_full v, out Input o) {
        o.customColor = abs(v.normal.y);
    }
	
    float _PeakLevel;
    float _RockLevel;
    float _GrassLevel;
    float _SandLevel;
    float _Slope;
    float _WaterLevel;
	
    void surf (Input IN, inout SurfaceOutput o) 
	{
		// snow
        if (IN.worldPos.y >= _PeakLevel)
            o.Albedo = tex2D(_PeakTex, IN.uv_WaterTex).rgb;
		
		// stone
        if (IN.worldPos.y <= _RockLevel)
            o.Albedo = lerp(tex2D(_RockTex, IN.uv_WaterTex).rgb, tex2D(_PeakTex, IN.uv_WaterTex).rgb, (IN.worldPos.y - _RockLevel)/_PeakLevel);
		
		// grass	
        if (IN.worldPos.y <= _GrassLevel)
//            o.Albedo = lerp(tex2D(_GrassTex, IN.uv_WaterTex).rgb, tex2D(_RockTex, IN.uv_WaterTex).rgb, (IN.worldPos.y - _GrassLevel)/(_RockLevel - _GrassLevel));
           o.Albedo = lerp(tex2D(_GrassTex, IN.uv_WaterTex).rgb, tex2D(_RockTex, IN.uv_WaterTex).rgb, (IN.worldPos.y - _GrassLevel)/_PeakLevel);

		// sand
		if (IN.worldPos.y <= _SandLevel)
            o.Albedo = lerp(tex2D(_SandTex, IN.uv_WaterTex).rgb, tex2D(_GrassTex, IN.uv_WaterTex).rgb, (IN.worldPos.y - _SandLevel)/_PeakLevel);
        
		// water
		if (IN.worldPos.y <= _WaterLevel)
            o.Albedo = tex2D(_WaterTex, IN.uv_WaterTex).rgb;
			
        o.Albedo *= saturate(IN.customColor + _Slope);          
    }
    ENDCG
}
Fallback "Diffuse"
}