OutlineEx.shader 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. Shader "TSF Shaders/UI/OutlineEx"
  2. {
  3. Properties
  4. {
  5. _MainTex ("Main Texture", 2D) = "white" {}
  6. _Color ("Tint", Color) = (1, 1, 1, 1)
  7. //_OutlineColor ("Outline Color", Color) = (1, 1, 1, 1)
  8. //_OutlineWidth ("Outline Width", Int) = 1
  9. _StencilComp ("Stencil Comparison", Float) = 8
  10. _Stencil ("Stencil ID", Float) = 0
  11. _StencilOp ("Stencil Operation", Float) = 0
  12. _StencilWriteMask ("Stencil Write Mask", Float) = 255
  13. _StencilReadMask ("Stencil Read Mask", Float) = 255
  14. _ColorMask ("Color Mask", Float) = 15
  15. [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
  16. }
  17. SubShader
  18. {
  19. Tags
  20. {
  21. "Queue"="Transparent"
  22. "IgnoreProjector"="True"
  23. "RenderType"="Transparent"
  24. "PreviewType"="Plane"
  25. "CanUseSpriteAtlas"="True"
  26. }
  27. Stencil
  28. {
  29. Ref [_Stencil]
  30. Comp [_StencilComp]
  31. Pass [_StencilOp]
  32. ReadMask [_StencilReadMask]
  33. WriteMask [_StencilWriteMask]
  34. }
  35. Cull Off
  36. Lighting Off
  37. ZWrite Off
  38. ZTest [unity_GUIZTestMode]
  39. Blend SrcAlpha OneMinusSrcAlpha
  40. ColorMask [_ColorMask]
  41. Pass
  42. {
  43. Name "OUTLINE"
  44. CGPROGRAM
  45. #pragma vertex vert
  46. #pragma fragment frag
  47. //Add for RectMask2D
  48. #include "UnityUI.cginc"
  49. //End for RectMask2D
  50. sampler2D _MainTex;
  51. fixed4 _Color;
  52. fixed4 _TextureSampleAdd;
  53. float4 _MainTex_TexelSize;
  54. //float4 _OutlineColor;
  55. //int _OutlineWidth;
  56. //Add for RectMask2D
  57. float4 _ClipRect;
  58. //End for RectMask2D
  59. struct appdata
  60. {
  61. float4 vertex : POSITION;
  62. float4 tangent : TANGENT;
  63. float4 normal : NORMAL;
  64. float2 texcoord : TEXCOORD0;
  65. float2 uv1 : TEXCOORD1;
  66. float2 uv2 : TEXCOORD2;
  67. float2 uv3 : TEXCOORD3;
  68. fixed4 color : COLOR;
  69. };
  70. struct v2f
  71. {
  72. float4 vertex : SV_POSITION;
  73. float4 tangent : TANGENT;
  74. float4 normal : NORMAL;
  75. float2 texcoord : TEXCOORD0;
  76. float2 uv1 : TEXCOORD1;
  77. float2 uv2 : TEXCOORD2;
  78. float2 uv3 : TEXCOORD3;
  79. //Add for RectMask2D
  80. float4 worldPosition : TEXCOORD4;
  81. //End for RectMask2D
  82. fixed4 color : COLOR;
  83. };
  84. v2f vert(appdata IN)
  85. {
  86. v2f o;
  87. //Add for RectMask2D
  88. o.worldPosition = IN.vertex;
  89. //End for RectMask2D
  90. o.vertex = UnityObjectToClipPos(IN.vertex);
  91. o.tangent = IN.tangent;
  92. o.texcoord = IN.texcoord;
  93. o.color = IN.color * _Color;
  94. o.uv1 = IN.uv1;
  95. o.uv2 = IN.uv2;
  96. o.uv3 = IN.uv3;
  97. o.normal = IN.normal;
  98. return o;
  99. }
  100. /*
  101. fixed IsInRect(float2 pPos, float4 pClipRect)
  102. {
  103. pPos = step(pClipRect.xy, pPos) * step(pPos, pClipRect.zw);
  104. return pPos.x * pPos.y;
  105. }
  106. */
  107. fixed IsInRect(float2 pPos, float2 pClipRectMin, float2 pClipRectMax)
  108. {
  109. pPos = step(pClipRectMin, pPos) * step(pPos, pClipRectMax);
  110. return pPos.x * pPos.y;
  111. }
  112. fixed SampleAlpha(int pIndex, v2f IN)
  113. {
  114. const fixed sinArray[12] = { 0, 0.5, 0.866, 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5 };
  115. const fixed cosArray[12] = { 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5, 0, 0.5, 0.866 };
  116. float2 pos = IN.texcoord + _MainTex_TexelSize.xy * float2(cosArray[pIndex], sinArray[pIndex]) * IN.tangent.x; //normal.z 存放 _OutlineWidth
  117. return IsInRect(pos, IN.uv1, IN.uv2) * (tex2D(_MainTex, pos) + _TextureSampleAdd).w * IN.tangent.w; //tangent.w 存放 _OutlineColor.w
  118. }
  119. fixed4 frag(v2f IN) : SV_Target
  120. {
  121. fixed4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
  122. if (IN.tangent.x > 0) //normal.z 存放 _OutlineWidth
  123. {
  124. color.w *= IsInRect(IN.texcoord, IN.uv1, IN.uv2); //uv1 uv2 存着原始字的uv长方形区域大小
  125. half4 val = half4(IN.uv3.x, IN.uv3.y, IN.tangent.z, 0); //uv3.xy tangent.z 分别存放着 _OutlineColor的rgb
  126. val.w += SampleAlpha(0, IN);
  127. val.w += SampleAlpha(1, IN);
  128. val.w += SampleAlpha(2, IN);
  129. val.w += SampleAlpha(3, IN);
  130. val.w += SampleAlpha(4, IN);
  131. val.w += SampleAlpha(5, IN);
  132. val.w += SampleAlpha(6, IN);
  133. val.w += SampleAlpha(7, IN);
  134. val.w += SampleAlpha(8, IN);
  135. val.w += SampleAlpha(9, IN);
  136. val.w += SampleAlpha(10, IN);
  137. val.w += SampleAlpha(11, IN);
  138. color = (val * (1.0 - color.a)) + (color * color.a);
  139. color.a *= IN.color.a*IN.color.a*IN.color.a; //字逐渐隐藏时,描边也要隐藏
  140. }
  141. //Add for RectMask2D
  142. color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
  143. #ifdef UNITY_UI_ALPHACLIP
  144. clip(color.a - 0.001);
  145. #endif
  146. //End for RectMask2D
  147. return color;
  148. }
  149. ENDCG
  150. }
  151. }
  152. }