unity 百葉窗效果 shader 兩行代碼搞定

兩行shader代碼搞定百葉窗效果!!!

先看下效果:
在這裏插入圖片描述
直接上shader代碼:

Shader "Learning/baiyechuang"
{
	Properties
	{
		_TopTex ("TopTexture", 2D) = "white" {}
		_BottomTex ("BottomTexture", 2D) = "white" {}
		_ColumnCount("ColumnCount", int) = 3
		_RowCount("RowCount", int) = 3
		_ShowPercent_Col("ShowPercent_Col", range(0, 1)) = 0.5
		_ShowPercent_Row("ShowPercent_Row", range(0, 1)) = 0.5
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			sampler2D _TopTex;
			sampler2D _BottomTex;
			int _ColumnCount;
			int _RowCount;
			float _ShowPercent_Col;
			float _ShowPercent_Row;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				float2 nuv = frac(i.uv * float2(_ColumnCount, _RowCount));
				return lerp(tex2D(_TopTex, i.uv), tex2D(_BottomTex, i.uv), step(step(_ShowPercent_Col, nuv.x) + step(_ShowPercent_Row, nuv.y), 0.5));
			}

			ENDCG
		}
	}
}

主要思路:
把圖片分成幾行或者幾列,通過計算,決定當前像素點顯示哪個圖的像素,通過調節閾值可以達到動態的效果。

shader實現的代碼很簡單,只有frag shader中的兩行代碼,下面拆分一下這兩行代碼,進行解釋

float2 nuv = frac(i.uv * float2(_ColumnCount, _RowCount));
int col_show = step(_ShowPercent_Col, nuv.x);
int row_show = step(_ShowPercent_Row, nuv.y);
int show_tex = step(col_show + row_show, 0.5);
fixed4 col = 0;
col = lerp(tex2D(_TopTex, i.uv), tex2D(_BottomTex, i.uv), show_tex);
return col;

line1:
通過uv取每個部分的小數部分,也就是把uv座標轉化爲再這一部分中的對應比例,如下圖
在這裏插入圖片描述
P點是任意一個像素點,代碼中nuv.x就是P點左邊黃線算起,在第二格中的百分比。

line2,line3:
計算任意像點的百分比和輸入的閾值作比較,大於閾值返回0,小於閾值返回1。

line4:
橫縱的結果相加可得到三種值:0,1,2,跟0.5相比,大於0.5返回1,小於0.5返回0,這個值會在下面代碼用到

line6:
用於判斷當前uv點顯示哪張圖片的像素,使用lerp函數,差值爲0或1,可以理解爲取兩個極端,就是判斷用哪張圖片的像素,這個差值就是line4的到的值。

以上就是各個代碼的含義,可能因爲用了step函數導致不容易理解,其實使用setp函數就是爲了避免使用if else的邏輯判斷語句,這樣可以增加shader的效率。這段shader最終的形成也是根據邏輯判斷語句簡化成現在這個樣子。
在文章的結束貼上一個用if else實現的邏輯,可以方便理解:

fixed4 frag (v2f i) : SV_Target
{
	float2 nuv = frac(i.uv * float2(_ColumnCount, _RowCount));
	bool col_show = nuv.x > _ShowPercent_Col;
	bool row_show = nuv.y > _ShowPercent_Row;
	if (col_show || row_show) {
		return tex2D(_TopTex, i.uv);
	}
	else {
		return tex2D(_BottomTex, i.uv);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章