3 Color linear gradient shader

Hi all,

Im trying to adapt this shader to take 3 colors and create a gradient from them. But I just can’t seem to figure out why its not working. The idea is to check whether we are passed the mid point of the image or not and change the transition of the image but the middle color does not look solid and the transitions can sometimes change color. Any guidance is appreciated.

Shader "Custom/Gradient_3Color"
{
 Properties {
     [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
     _Color ("Top Color", Color) = (1,1,1,1)
     _Color2 ("Mid Color", Color) = (1,1,1,1)
     _Color3 ("Bot Color", Color) = (1,1,1,1)
     _Scale ("Middle", Range(0, 1)) = 1
 }
  
 SubShader {
     Tags {"Queue"="Background"  "IgnoreProjector"="True"}
     LOD 100
  
     ZWrite On
  
     Pass {
         CGPROGRAM
         #pragma vertex vert  
         #pragma fragment frag
         #include "UnityCG.cginc"
  
         fixed4 _Color;
         fixed4 _Color2;
         fixed4 _Color3;
         fixed  _Scale;
  
         struct v2f {
             float4 pos : SV_POSITION;
             fixed4 col : COLOR;
         };
  
         v2f vert (appdata_full v)
         {
             v2f o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             o.col = step(_Scale, v.texcoord.y) * lerp(_Color2, _Color, v.texcoord.y) + step(v.texcoord.y, _Scale) * lerp(_Color3, _Color2, v.texcoord.y );
//             o.col = lerp(_Color, _Color2, v.texcoord.y );
//             o.col = half4( v.vertex.y, 0, 0, 1);
             return o;
         }
        
  
         float4 frag (v2f i) : COLOR {
             float4 c = i.col;
             c.a = 1;
             return c;
         }
             ENDCG
         }
     }
 }

The main issue is that this is not something that you want to do in the vertex shader. You’ve only got 4 vertices on a sprite, so those are the only data points the fragment shader has to work with. The alternative of adding vertices in the correct locations is probably not what you want to do either.

I took the liberty of sticking it in a fragment shader and cleaning it up a tad for you:

Shader "Custom/Gradient_3Color" {
	Properties {
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_ColorTop ("Top Color", Color) = (1,1,1,1)
		_ColorMid ("Mid Color", Color) = (1,1,1,1)
		_ColorBot ("Bot Color", Color) = (1,1,1,1)
		_Middle ("Middle", Range(0.001, 0.999)) = 1
	}

	SubShader {
		Tags {"Queue"="Background"  "IgnoreProjector"="True"}
		LOD 100

		ZWrite On

		Pass {
		CGPROGRAM
		#pragma vertex vert  
		#pragma fragment frag
		#include "UnityCG.cginc"

		fixed4 _ColorTop;
		fixed4 _ColorMid;
		fixed4 _ColorBot;
		float  _Middle;

		struct v2f {
			float4 pos : SV_POSITION;
			float4 texcoord : TEXCOORD0;
		};

		v2f vert (appdata_full v) {
			v2f o;
			o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
			o.texcoord = v.texcoord;
			return o;
		}

		fixed4 frag (v2f i) : COLOR {
			fixed4 c = lerp(_ColorBot, _ColorMid, i.texcoord.y / _Middle) * step(i.texcoord.y, _Middle);
			c += lerp(_ColorMid, _ColorTop, (i.texcoord.y - _Middle) / (1 - _Middle)) * step(_Middle, i.texcoord.y);
			c.a = 1;
			return c;
		}
		ENDCG
		}
	}
}

It helps to call the variables more what they are instead of _Color2 etc. It’ll save you headache :slight_smile:

sir thanks you are hero :stuck_out_tongue: