Fragment shader---片段级模型动态变色2

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有关

修改后:







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值