- Home /
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
}
}
}
Answer by JonathanCzeck · Dec 07, 2015 at 03:28 AM
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 :)
Wow, that worked like a charm. I wasn't aware of the differences between frag and vert. Thank you very much :D
Do you know how to make the gradient "move with the Object"? I mean if I move the mesh the gradient stays in the same place.
Avoiding names like _Color2 is a good idea, still everyone insist on calling vertex vert and fragment frag tho ;)
Do you know how to apply this gradient just toward z direction? https://answers.unity.com/questions/1456021/shader-for-pixel-colour-just-based-on-z-position.html
I found bug in formula. What happening if i.texcoord.y is equal _Middle? It is equal _ColorMid += _ColorMid
This formula prevent from this situation
c += lerp(_ColorMid, _ColorTop, (i.texcoord.y - _Middle) / (1 - _Middle)) * (1 - step(i.texcoord.y, _Middle));
Your answer
Follow this Question
Related Questions
Fog of War overlay for overhead map. 1 Answer
Unity crashes when trying to run depth shader with color lerp. 1 Answer
UI Triangle Color picker 0 Answers
Getting 3D Meshes to render with UI according to heirarchy 0 Answers
Need Mask Shader . 0 Answers