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);
	}
}

猜你喜欢

转载自blog.csdn.net/YuAnHandSome/article/details/106547686