Unity Shader 圖片流光效果實現(純計算方式)


Unity Shader 圖片流光效果實現(純計算方式)

shader源碼如下

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/StreamerLight" {
	Properties{
		_MainTex("Texture", 2D) = "white" { }
		_Angle("Angle", Float) = 45		//光帶的傾斜角度
		_Width("Width",Float)=0.65		//光帶的寬度
		_Interval("Interval",Float)=3	//間隔時間
		_BeginTime("BeginTime",Float)=0	//開始時間
		_OffestX("OffestX",Float)=0.6	//光帶邊界的偏移量
		_LoopTime("LoopTime",Float)=0.7	//單次的循環時間
	}
		SubShader
	{
	Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
	Blend SrcAlpha OneMinusSrcAlpha
		AlphaTest Greater 0.1
		pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			half _Angle;
			half _Width;
			half _Interval;
			half _BeginTime;
			half _OffestX;
			half _LoopTime;

			sampler2D _MainTex;
			float4 _MainTex_ST;

			struct v2f {
				float4  pos : SV_POSITION;
				float2  uv : TEXCOORD0;
			};

			//頂點函數沒什么特別的,和常規一樣
			v2f vert(appdata_base v)
			{
				v2f o;
				   o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
				return o;
			}

			//必須放在使用其的 frag函數之前,否則無法識別。
			//核心:計算函數,角度,uv,光帶的x長度,間隔,開始時間,偏移,單次循環時間
			 float inFlash(float angle,float2 uv,float xLength,int interval,int beginTime, float offX, float loopTime)
			{
				 //亮度值
				 float brightness = 0;

				 //傾斜角
				 float angleInRad = 0.0174444 * angle;

				 //當前時間
				 float currentTime = _Time.y;

				 //獲取本次光照的起始時間
				 int currentTimeInt = _Time.y / interval;
				 currentTimeInt *= interval;

				 //獲取本次光照的流逝時間 = 當前時間 - 起始時間
				 float currentTimePassed = currentTime - currentTimeInt;
				 if (currentTimePassed > beginTime)
				 {
					 //底部左邊界和右邊界
					 float xBottomLeftBound;
					 float xBottomRightBound;

					 //此點邊界
					 float xPointLeftBound;
					 float xPointRightBound;

					 float x0 = currentTimePassed - beginTime;
					 x0 /= loopTime;

					 //設置右邊界
					 xBottomRightBound = x0;

					 //設置左邊界
					 xBottomLeftBound = x0 - xLength;

					 //投影至x的長度 = y/ tan(angle)
					 float xProjL;
					 xProjL = (uv.y) / tan(angleInRad);

					 //此點的左邊界 = 底部左邊界 - 投影至x的長度
					 xPointLeftBound = xBottomLeftBound - xProjL;
					 //此點的右邊界 = 底部右邊界 - 投影至x的長度
					 xPointRightBound = xBottomRightBound - xProjL;

					 //邊界加上一個偏移
					 xPointLeftBound += offX;
					 xPointRightBound += offX;

					 //如果該點在區域內
					 if (uv.x > xPointLeftBound && uv.x < xPointRightBound)
					 {
						 //得到發光區域的中心點
						 float midness = (xPointLeftBound + xPointRightBound) / 2;

						 //趨近中心點的程度,0表示位於邊緣,1表示位於中心點
						 float rate = (xLength - 2 * abs(uv.x - midness)) / (xLength);
						 brightness = rate;
					 }
				 }
				 brightness = max(brightness,0);
				 brightness = min(brightness, 0.75);

				 //返回顏色 = 純白色 * 亮度
				 float4 col = float4(1,1,1,1) *brightness;
				 return brightness;
			 }

			 float4 frag(v2f i) : COLOR
			 {
				  float4 outp;

			 //根據uv取得紋理顏色,和常規一樣
			float4 texCol = tex2D(_MainTex,i.uv);

			//傳進i.uv等參數,得到亮度值
			float tmpBrightness;
			tmpBrightness = inFlash(_Angle,i.uv,_Width,_Interval,_BeginTime,_OffestX,_LoopTime);

			//圖像區域,判定設置為 顏色的A > 0.5,輸出為材質顏色+光亮值
			if (texCol.w > 0.5)
					outp = texCol + float4(1,1,1,1)*tmpBrightness;
			//空白區域,判定設置為 顏色的A <=0.5,輸出空白
			else
				outp = float4(0,0,0,0);

			return outp;
			}
		ENDCG
	}
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM