RectBorder.shader 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. //矩形边界(圆角、描边)
  2. Shader "JC/UI/RectBorder"
  3. {
  4. Properties
  5. {
  6. [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
  7. _Color("Tint", Color) = (1,1,1,1)
  8. _StencilComp("Stencil Comparison", Float) = 8
  9. _Stencil("Stencil ID", Float) = 0
  10. _StencilOp("Stencil Operation", Float) = 0
  11. _StencilWriteMask("Stencil Write Mask", Float) = 255
  12. _StencilReadMask("Stencil Read Mask", Float) = 255
  13. _ColorMask("Color Mask", Float) = 15
  14. [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip("Use Alpha Clip", Float) = 0
  15. _NodeWidth("Node Width", Float) = 100
  16. _NodeHeight("Node Height", Float) = 100
  17. _BorderRadius("Border Radius", Float) = 20
  18. _BorderRadiusSwitch("Border Radius Switch", Int) = 15
  19. _BorderWidth("Border Width", Float) = 2
  20. _BorderColor("Border Color", Color) = (0,0,0,1)
  21. }
  22. SubShader
  23. {
  24. Tags
  25. {
  26. "Queue" = "Transparent"
  27. "IgnoreProjector" = "True"
  28. "RenderType" = "Transparent"
  29. "PreviewType" = "Plane"
  30. "CanUseSpriteAtlas" = "True"
  31. }
  32. Stencil
  33. {
  34. Ref[_Stencil]
  35. Comp[_StencilComp]
  36. Pass[_StencilOp]
  37. ReadMask[_StencilReadMask]
  38. WriteMask[_StencilWriteMask]
  39. }
  40. Cull Off
  41. Lighting Off
  42. ZWrite Off
  43. ZTest[unity_GUIZTestMode]
  44. Blend SrcAlpha OneMinusSrcAlpha
  45. ColorMask[_ColorMask]
  46. Pass
  47. {
  48. CGPROGRAM
  49. #pragma vertex vert
  50. #pragma fragment frag
  51. #include "UnityCG.cginc"
  52. #include "UnityUI.cginc"
  53. #pragma multi_compile __ UNITY_UI_ALPHACLIP
  54. struct appdata_t
  55. {
  56. float4 vertex :
  57. POSITION;
  58. float4 color :
  59. COLOR;
  60. float2 texcoord :
  61. TEXCOORD0;
  62. };
  63. struct v2f
  64. {
  65. float4 vertex :
  66. SV_POSITION;
  67. fixed4 color :
  68. COLOR;
  69. half2 texcoord :
  70. TEXCOORD0;
  71. float4 worldPosition :
  72. TEXCOORD1;
  73. };
  74. fixed4 _Color;
  75. fixed4 _TextureSampleAdd;
  76. float4 _ClipRect;
  77. float _NodeWidth;
  78. float _NodeHeight;
  79. float _BorderRadius;
  80. int _BorderRadiusSwitch;
  81. float _BorderWidth;
  82. fixed4 _BorderColor;
  83. float4 _MainTex_TexelSize;
  84. v2f vert(appdata_t IN)
  85. {
  86. v2f OUT;
  87. OUT.worldPosition = IN.vertex;
  88. OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
  89. OUT.texcoord = IN.texcoord;
  90. #ifdef UNITY_HALF_TEXEL_OFFSET
  91. OUT.vertex.xy += (_ScreenParams.zw - 1.0)*float2(-1,1);
  92. #endif
  93. OUT.color = IN.color * _Color;
  94. return OUT;
  95. }
  96. sampler2D _MainTex;
  97. fixed4 frag(v2f IN) : SV_Target
  98. {
  99. half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
  100. color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
  101. #ifdef UNITY_UI_ALPHACLIP
  102. clip(color.a - 0.001);
  103. #endif
  104. // float w = _MainTex_TexelSize.z;
  105. // float h = _MainTex_TexelSize.w;
  106. float w = _NodeWidth;
  107. float h = _NodeHeight;
  108. float r = _BorderRadius;
  109. float x = IN.texcoord.x * w;
  110. float y = IN.texcoord.y * h;
  111. float bw = _BorderWidth;
  112. bool switch_lt = (_BorderRadiusSwitch & 1) == 1; //左上角是否要圆角处理
  113. bool switch_rt = (_BorderRadiusSwitch & 2) == 2; //右上角是否要圆角处理
  114. bool switch_rb = (_BorderRadiusSwitch & 4) == 4; //右下角是否要圆角处理
  115. bool switch_lb = (_BorderRadiusSwitch & 8) == 8; //左下角是否要圆角处理
  116. //左下角
  117. if (switch_lb && x < r && y < r)
  118. {
  119. if ((x - r) * (x - r) + (y - r) * (y - r) > (r - bw) * (r - bw))
  120. {
  121. if ((x - r) * (x - r) + (y - r) * (y - r) > r * r)
  122. color.a = 0;
  123. else
  124. color.rgba = _BorderColor.rgba;
  125. }
  126. }
  127. //左上角
  128. else if (switch_lt && x < r && y > (h - r))
  129. {
  130. if ((x - r) * (x - r) + (y - (h - r)) * (y - (h - r)) > (r - bw) * (r - bw))
  131. {
  132. if ((x - r) * (x - r) + (y - (h - r)) * (y - (h - r)) > r * r)
  133. color.a = 0;
  134. else
  135. color.rgba = _BorderColor.rgba;
  136. }
  137. }
  138. //右下角
  139. else if (switch_rb && x > (w - r) && y < r)
  140. {
  141. if ((x - (w - r)) * (x - (w - r)) + (y - r) * (y - r) > (r - bw) * (r - bw))
  142. {
  143. if ((x - (w - r)) * (x - (w - r)) + (y - r) * (y - r) > r * r)
  144. color.a = 0;
  145. else
  146. color.rgba = _BorderColor.rgba;
  147. }
  148. }
  149. //右上角
  150. else if (switch_rt && x > (w - r) && y > (h - r))
  151. {
  152. if ((x - (w - r)) * (x - (w - r)) + (y - (h - r)) * (y - (h - r)) > (r - bw) * (r - bw))
  153. {
  154. if ((x - (w - r)) * (x - (w - r)) + (y - (h - r)) * (y - (h - r)) > r * r)
  155. color.a = 0;
  156. else
  157. color.rgba = _BorderColor.rgba;
  158. }
  159. }
  160. //边界上色
  161. else if (bw > 0 && x < bw || x > w - bw || y < bw || y > h - bw) color.rgba = _BorderColor.rgba;
  162. return color;
  163. }
  164. ENDCG
  165. }
  166. }
  167. }