您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么在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 } } }
關于怎么在Unity中利用shader實現一個百葉窗特效就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。