Unity shader實現(xiàn)百葉窗特效
本文實例為大家分享了Unity shader百葉窗展示的具體代碼,供大家參考,具體內(nèi)容如下
1.將圖片劃分為水平N欄,代碼如下:
Shader "Unlit/BYCShader"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_Lan("Lan",Float) = 10
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = v.texcoord;
OUT.color = v.color;
return OUT;
}
sampler2D _MainTex;
float _Lan;
float4 frag(v2f IN) : SV_Target
{
//從這裡開始
float2 uv = IN.texcoord;
uv.x*= _Lan;
uv.x = frac(uv.x);
return float4(uv.xy,1.0,1.0);
}
ENDCG
}
}
}

如上圖,劃分為N欄后,對每一欄進行單獨處理,即可做到每一欄都同時進行顏色消減。
2.對每一欄同時進行顏色消減(控制閾值可以通過c#代碼實現(xiàn))
代碼如下:
Shader "Unlit/BYCShader"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_Lan("Lan",Float) = 10
_StepX("StepX",Range(0.0,1.0))=1.0
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = v.texcoord;
OUT.color = v.color;
return OUT;
}
sampler2D _MainTex;
float _Lan;
float _StepX;
float4 frag(v2f IN) : SV_Target
{
float2 uv = IN.texcoord;
uv.x*= _Lan;
uv.x = frac(uv.x);
//從這裡開始,顏色值大於指定值stepx的進行消減
int needDiscard = step(_StepX,uv.x);
if(needDiscard == 1){
discard;
}
return float4(uv.xy,1.0,1.0);
}
ENDCG
}
}
}
效果如下:

3.加上切變,百葉窗在關(guān)閉打開時,是有透視變化的。用切變可以近似模擬透視,因為透視的實現(xiàn)代價很大,所以用切變。
添加一張圖片,并進行切變

代碼如下:
Shader "Unlit/BYCShader"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
_Lan("Lan",Float) = 10
_StepX("StepX",Range(0.0,1.0))=1.0
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
Name "Default"
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
#include "UnityUI.cginc"
#pragma multi_compile __ UNITY_UI_CLIP_RECT
#pragma multi_compile __ UNITY_UI_ALPHACLIP
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 worldPosition : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(appdata_t v)
{
v2f OUT;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.worldPosition = v.vertex;
OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
OUT.texcoord = v.texcoord;
OUT.color = v.color;
return OUT;
}
sampler2D _MainTex;
float _Lan;
float _StepX;
float4 frag(v2f IN) : SV_Target
{
//這裡進行裁剪
float2 uv = IN.texcoord;
uv.x*= _Lan;
uv.x = frac(uv.x);
int needDiscard = step(_StepX,uv.x);
if(needDiscard == 1){
discard;
}
//這里進行切變
float x1 = uv.x;
uv = IN.texcoord;
uv+=float2(-0.5,-0.5);
uv.x-=x1;//切變時,先將重心調(diào)整到中心,然后繞每一欄的起點進行切變(這里類似于繞某一點旋轉(zhuǎn),所以后面要進行反向操作,加了就減,減了就加)
float2x2 qiebian = float2x2(1,0,(1.0-_StepX),1);
uv = mul(qiebian,uv);
uv-=float2(-0.5,-0.5);
uv.x+=x1;
float4 color= tex2D(_MainTex, uv);
return color;
}
ENDCG
}
}
}
效果如下:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
c#使用htmlagilitypack解析html格式字符串
這篇文章主要介紹了c#使用htmlagilitypack解析html格式字符串的示例,需要的朋友可以參考下2014-03-03
C# 9.0新特性——擴展方法GetEnumerator支持foreach循環(huán)
這篇文章主要介紹了C# 9.0新特性——擴展方法GetEnumerator支持foreach循環(huán)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c# 9.0,感興趣的朋友可以了解下2020-11-11
輕松學(xué)習(xí)C#的結(jié)構(gòu)和類
輕松學(xué)習(xí)C#的結(jié)構(gòu)和類,對C#的結(jié)構(gòu)和類感興趣的朋友可以參考本篇文章,幫助大家更靈活的運用C#的結(jié)構(gòu)和類2015-11-11

