首页 > 编程 > C# > 正文

Unity shader实现百叶窗特效

2020-01-23 20:45:56
字体:
来源:转载
供稿:网友

本文实例为大家分享了Unity shader百叶窗展示的具体代码,供大家参考,具体内容如下

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#代码实现)

代码如下:

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.加上切变,百叶窗在关闭打开时,是有透视变化的。用切变可以近似模拟透视,因为透视的实现代价很大,所以用切变。

添加一张图片,并进行切变

代码如下:

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;//切,先重心整到中心,然后绕每一栏的起点进行切变(这里类似于绕某一点旋转,所以后面要进行反向操作,加了就减,减了就加)    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  } }}

效果如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表