参考链接:
https://blog.csdn.net/akof1314/article/details/50428200
1.Mask.shader
1 // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3 Shader "Custom/Mask" 4 { 5 Properties 6 { 7 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 8 _Color ("Tint", Color) = (1,1,1,1) 9 10 _StencilComp ("Stencil Comparison", Float) = 8 11 _Stencil ("Stencil ID", Float) = 0 12 _StencilOp ("Stencil Operation", Float) = 0 13 _StencilWriteMask ("Stencil Write Mask", Float) = 255 14 _StencilReadMask ("Stencil Read Mask", Float) = 255 15 16 _ColorMask ("Color Mask", Float) = 15 17 18 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 19 20 _MaskTex ("Mask Texture", 2D) = "white" {} 21 } 22 23 SubShader 24 { 25 Tags 26 { 27 "Queue"="Transparent" 28 "IgnoreProjector"="True" 29 "RenderType"="Transparent" 30 "PreviewType"="Plane" 31 "CanUseSpriteAtlas"="True" 32 } 33 34 Stencil 35 { 36 Ref [_Stencil] 37 Comp [_StencilComp] 38 Pass [_StencilOp] 39 ReadMask [_StencilReadMask] 40 WriteMask [_StencilWriteMask] 41 } 42 43 Cull Off 44 Lighting Off 45 ZWrite Off 46 ZTest [unity_GUIZTestMode] 47 Blend SrcAlpha OneMinusSrcAlpha 48 ColorMask [_ColorMask] 49 50 Pass 51 { 52 Name "Default" 53 CGPROGRAM 54 #pragma vertex vert 55 #pragma fragment frag 56 #pragma target 2.0 57 58 #include "UnityCG.cginc" 59 #include "UnityUI.cginc" 60 61 #pragma multi_compile __ UNITY_UI_CLIP_RECT 62 #pragma multi_compile __ UNITY_UI_ALPHACLIP 63 64 struct appdata_t 65 { 66 float4 vertex : POSITION; 67 float4 color : COLOR; 68 float2 texcoord : TEXCOORD0; 69 UNITY_VERTEX_INPUT_INSTANCE_ID 70 }; 71 72 struct v2f 73 { 74 float4 vertex : SV_POSITION; 75 fixed4 color : COLOR; 76 float2 texcoord : TEXCOORD0; 77 float4 worldPosition : TEXCOORD1; 78 UNITY_VERTEX_OUTPUT_STEREO 79 }; 80 81 sampler2D _MainTex; 82 fixed4 _Color; 83 fixed4 _TextureSampleAdd; 84 float4 _ClipRect; 85 float4 _MainTex_ST; 86 87 sampler2D _MaskTex; 88 89 v2f vert(appdata_t v) 90 { 91 v2f OUT; 92 UNITY_SETUP_INSTANCE_ID(v); 93 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); 94 OUT.worldPosition = v.vertex; 95 OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); 96 97 OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); 98 99 OUT.color = v.color * _Color; 100 return OUT; 101 } 102 103 fixed4 frag(v2f IN) : SV_Target 104 { 105 half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; 106 color.a *= tex2D(_MaskTex, IN.texcoord).a; 107 108 #ifdef UNITY_UI_CLIP_RECT 109 color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); 110 #endif 111 112 #ifdef UNITY_UI_ALPHACLIP 113 clip (color.a - 0.001); 114 #endif 115 116 return color; 117 } 118 ENDCG 119 } 120 } 121 }
核心代码:
1 color.a *= tex2D(_MaskTex, IN.texcoord).a;
即遮罩图alpha=0的地方不会显示
遮罩图和效果图(遮罩图白色的地方实际上是透明的):
2.UV问题
上面的结果表面上看是没什么问题的,但如果把图片打进图集就会发现不对了。原因是,shader里面uv坐标不再是单个图片的坐标了,而是图集里面该图片的坐标,使得shader计算错误,最终渲染错乱。解决方法是,将单个图片的纹理坐标保存到uv1中。
SetVertUV1.cs
1 using UnityEngine; 2 using UnityEngine.UI; 3 4 public class SetVertUV1 : BaseMeshEffect 5 { 6 public override void ModifyMesh(VertexHelper vh) 7 { 8 UIVertex uiVertex = new UIVertex(); 9 for (int i = 0; i < vh.currentVertCount; i++) 10 { 11 vh.PopulateUIVertex(ref uiVertex, i); 12 int uvX = i >> 1; 13 int uvY = uvX ^ (i & 1); 14 uiVertex.uv1 = new Vector2(uvX, uvY); 15 vh.SetUIVertex(uiVertex, i); 16 } 17 } 18 }
即将4个顶点的uv1依次设置为(0,0),(0,1),(1,1),(1,0)
MaskUV1.shader
1 // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3 Shader "Custom/MaskUV1" 4 { 5 Properties 6 { 7 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 8 _Color ("Tint", Color) = (1,1,1,1) 9 10 _StencilComp ("Stencil Comparison", Float) = 8 11 _Stencil ("Stencil ID", Float) = 0 12 _StencilOp ("Stencil Operation", Float) = 0 13 _StencilWriteMask ("Stencil Write Mask", Float) = 255 14 _StencilReadMask ("Stencil Read Mask", Float) = 255 15 16 _ColorMask ("Color Mask", Float) = 15 17 18 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 19 20 _MaskTex ("Mask Texture", 2D) = "white" {} 21 } 22 23 SubShader 24 { 25 Tags 26 { 27 "Queue"="Transparent" 28 "IgnoreProjector"="True" 29 "RenderType"="Transparent" 30 "PreviewType"="Plane" 31 "CanUseSpriteAtlas"="True" 32 } 33 34 Stencil 35 { 36 Ref [_Stencil] 37 Comp [_StencilComp] 38 Pass [_StencilOp] 39 ReadMask [_StencilReadMask] 40 WriteMask [_StencilWriteMask] 41 } 42 43 Cull Off 44 Lighting Off 45 ZWrite Off 46 ZTest [unity_GUIZTestMode] 47 Blend SrcAlpha OneMinusSrcAlpha 48 ColorMask [_ColorMask] 49 50 Pass 51 { 52 Name "Default" 53 CGPROGRAM 54 #pragma vertex vert 55 #pragma fragment frag 56 #pragma target 2.0 57 58 #include "UnityCG.cginc" 59 #include "UnityUI.cginc" 60 61 #pragma multi_compile __ UNITY_UI_CLIP_RECT 62 #pragma multi_compile __ UNITY_UI_ALPHACLIP 63 64 struct appdata_t 65 { 66 float4 vertex : POSITION; 67 float4 color : COLOR; 68 float2 texcoord : TEXCOORD0; 69 float2 texcoord1 : TEXCOORD1; 70 UNITY_VERTEX_INPUT_INSTANCE_ID 71 }; 72 73 struct v2f 74 { 75 float4 vertex : SV_POSITION; 76 fixed4 color : COLOR; 77 float2 texcoord : TEXCOORD0; 78 float4 worldPosition : TEXCOORD1; 79 float2 texcoord1 : TEXCOORD2; 80 UNITY_VERTEX_OUTPUT_STEREO 81 }; 82 83 sampler2D _MainTex; 84 fixed4 _Color; 85 fixed4 _TextureSampleAdd; 86 float4 _ClipRect; 87 float4 _MainTex_ST; 88 89 sampler2D _MaskTex; 90 91 v2f vert(appdata_t v) 92 { 93 v2f OUT; 94 UNITY_SETUP_INSTANCE_ID(v); 95 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); 96 OUT.worldPosition = v.vertex; 97 OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); 98 99 OUT.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); 100 101 OUT.color = v.color * _Color; 102 OUT.texcoord1 = v.texcoord1; 103 return OUT; 104 } 105 106 fixed4 frag(v2f IN) : SV_Target 107 { 108 half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; 109 color.a *= tex2D(_MaskTex, IN.texcoord1).a; 110 111 #ifdef UNITY_UI_CLIP_RECT 112 color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); 113 #endif 114 115 #ifdef UNITY_UI_ALPHACLIP 116 clip (color.a - 0.001); 117 #endif 118 119 return color; 120 } 121 ENDCG 122 } 123 } 124 }