[UnityShader效果]01.Mask

参考链接:

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 }

猜你喜欢

转载自www.cnblogs.com/lyh916/p/10746156.html