This is pretty straightforward. I'll add it to a standard shader and comment on it as we go...

Shader "Custom/TwoTone" { Properties { // Add a second color property _Color ("Color", Color) = (1,1,1,1) _Color2 ("Second Color", Color) = (1, 0, 0, 1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 // And a divider to store our transition plane _Divider ("Divider", Vector) = (0, 1, 0, 1) } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard fullforwardshadows #pragma target 3.0 sampler2D _MainTex; struct Input { float2 uv_MainTex; float3 worldPos; }; half _Glossiness; half _Metallic; UNITY_INSTANCING_BUFFER_START(Props) // Color divider properties here for instancing, if desired. fixed4 _Color; fixed4 _Color2; float4 _Divider; UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutputStandard o) { // Compute the "height" of this point along the dividing axis. float level = dot(IN.worldPos, _Divider.xyz); // Select one of the two colours, // depending on the threshold in the fourth component. fixed4 color = level > _Divider.w ? _Color2 : _Color; fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * color; o.Albedo = c.rgb; o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
The trick here is the _Divider property. The first three components of this vector, xyz represent the direction the line moves (the transition plane's normal vector). So by changing those you can make the split run top-to-bottom, left-to-right, whatever direction you need.
The last component w represents the height along that axis where the colour transition should happen. By sliding this value up and down, you move the transition plane.
Right now I'm doing the comparison in world space, but you can also do this in object space so the transition plane moves with the object rather than staying at a fixed spot in the world.
(A previous version of this answer used the step function, but it's come to my attention that a ternary is just as fast if not faster)