1、不用if...else...语句返回颜色值
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/s_f_color" {
Properties {
_MainColor ("_MainColor", Color) = (1,1,1,1)
_SecondColor("SecondColor",color)=(1,1,1,1)
_Center("Center",range(-0.5,0.5))=0
}
SubShader{
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
float4 _MainColor;
float4 _SecondColor;
float _Center;
struct v2f {
float4 pos:POSITION;
float y:TEXTCOORD0;
};
v2f vert(appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.y = v.vertex.y;
return o;
}
fixed4 frag(v2f IN) :COLOR{
float d = IN.y - _Center;
//求d正值还是负值
d = d / abs(d);
d = d / 2+0.5;
//lertp的意思是_MainColor*(1-d)+_SecondColor*(1+d)
return lerp(_MainColor, _SecondColor, d);
}
ENDCG
}
}
}
着色后的结果:
2、cube有一部分没有着色成功
原因:给的center范围刚好是0.5,与物体的临界点刚好是重合的,所以会在浮点数的精度上有一个偏差
解决办法:将Center的范围由0.5改为0.51
由
改为
此时着色正常:
3、将颜色进行融合。需要解决的是上面参与融合的颜色有多大范围,下面参与融合的颜色有多大范围。
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/s_f_color" {
Properties {
_MainColor ("_MainColor", Color) = (1,1,1,1)
_SecondColor("SecondColor",color)=(1,1,1,1)
_Center("Center",range(-0.51,0.51))=0
_R("R",range(0,0.5))=0.2
}
SubShader{
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
float4 _MainColor;
float4 _SecondColor;
float _Center;
float _R;
struct v2f {
float4 pos:POSITION;
float y:TEXTCOORD0;
};
v2f vert(appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.y = v.vertex.y;
return o;
}
fixed4 frag(v2f IN) :COLOR{
//上半部分的融合
if (IN.y > _Center + _R) {
return _MainColor;
}
else if (IN.y>_Center &&IN.y<_Center+_R) { //处于上半部分,并处于融合带
float d = IN.y - _Center; //融合带的长度
d = (1-d/_R) - 0.5; //融合率。d/r的值介于0~1之间。当处于center的时候,值为0,所以用1-d/r进行反转,得到的是1.但是融合部分不能取1,只能取0.5,所以需要再减0.5
d = saturate(d); //上面的值可能会为-0.5,所以需要对上面的值进行一个限定,限定到0~1之间,因为它不可能到1,最大是0.5,所以限定在了0~0.5之间
return lerp(_MainColor, _SecondColor, d); //融合颜色
}
//下半部分的融合
if(IN.y<=_Center-_R){
return _SecondColor;
}
else if (IN.y<_Center && IN.y>_Center-_R) {
float d = _Center-IN.y ; //融合带的长度
d = (1 - d / _R) - 0.5; //融合率。d/r的值介于0~1之间。当处于center的时候,值为0,所以用1-d/r进行反转,得到的是1.但是融合部分不能取1,只能取0.5,所以需要再减0.5
d = saturate(d); //上面的值可能会为-0.5,所以需要对上面的值进行一个限定,限定到0~1之间,因为它不可能到1,最大是0.5,所以限定在了0~0.5之间
return lerp(_MainColor, _SecondColor, 1-d); //融合颜色
}
return _SecondColor;
}
ENDCG
}
}
}
着色结果:
4、去掉if...else语句
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/s_f_color" {
Properties {
_MainColor ("MainColor", Color) = (1,1,1,1)
_SecondColor("SecondColor",color)=(1,1,1,1)
_Center("Center",range(-0.51,0.51))=0
_R("R",range(0,0.5))=0.2
}
SubShader{
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
float4 _MainColor;
float4 _SecondColor;
float _Center;
float _R;
struct v2f {
float4 pos:POSITION;
float y:TEXTCOORD0;
};
v2f vert(appdata_base v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.y = v.vertex.y;
return o;
}
fixed4 frag(v2f IN) :COLOR{
float d = IN.y - _Center; //求距离
float s = abs(d); //对距离求绝对值
d=d/s;
float f = s / _R;
f = saturate(f);
d *= f;
d = d / 2 + 0.5;
return lerp(_MainColor, _SecondColor,d);
}
ENDCG
}
}
}
5、当center值拖动到最上面或者是最下面的时候,颜色不是纯色,而是仍然是有融合的颜色
解决办法:加大center的值,大小与融合半径R有关
修改后: