溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Unity中利用shader實現(xiàn)一個百葉窗特效

發(fā)布時間:2021-04-17 16:28:53 來源:億速云 閱讀:186 作者:Leah 欄目:編程語言

這篇文章給大家介紹怎么在Unity中利用shader實現(xiàn)一個百葉窗特效,內(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
  }
 }
}

怎么在Unity中利用shader實現(xiàn)一個百葉窗特效

如上圖,劃分為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
  }
 }
}

效果如下:

怎么在Unity中利用shader實現(xiàn)一個百葉窗特效

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

添加一張圖片,并進行切變

怎么在Unity中利用shader實現(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
  }
 }
}

關于怎么在Unity中利用shader實現(xiàn)一個百葉窗特效就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI