裁剪UI区域

作者:追风剑情 发布于:2018-12-19 11:30 分类:Shader

Shader代码

  1. Shader "Custom/UIClipTest"
  2. {
  3. Properties
  4. {
  5. [PerRendererData]
  6. _MainTex ("Texture", 2D) = "white" {}
  7.  
  8. [Toggle(UNITY_UI_CLIP_RECT)]
  9. _UseUIClipRect ("Use Rect Clip", Float) = 1
  10.  
  11. [Toggle(UNITY_UI_ALPHACLIP)]
  12. _UseUIAlphaClip ("Use Alpha Clip", Float) = 1
  13. }
  14. SubShader
  15. {
  16. LOD 100
  17.  
  18. Tags
  19. {
  20. "LightMode"="ForwardBase"
  21. "Queue" = "Transparent"
  22. "IgnoreProjector" = "True"
  23. "RenderType" = "Transparent"
  24. "PreviewType"="Plane"
  25. }
  26.  
  27. Pass
  28. {
  29. CGPROGRAM
  30. #pragma vertex vert
  31. #pragma fragment frag
  32. #include "UnityCG.cginc"
  33. #include "UnityUI.cginc"
  34.  
  35. //定义宏
  36. #pragma multi_compile __ UNITY_UI_CLIP_RECT
  37. #pragma multi_compile __ UNITY_UI_ALPHACLIP
  38.  
  39. struct appdata
  40. {
  41. //世界坐标
  42. float4 vertex : POSITION;
  43. //纹理坐标
  44. float2 uv : TEXCOORD0;
  45. };
  46.  
  47. struct v2f
  48. {
  49. //裁剪空间坐标
  50. float4 vertex : SV_POSITION;
  51. //纹理坐标
  52. float2 uv : TEXCOORD0;
  53. //世界坐标
  54. float4 worldPosition : TEXCOORD1;
  55. };
  56.  
  57. sampler2D _MainTex;
  58. float4 _MainTex_ST;
  59. float4 _ClipRect;
  60.  
  61. v2f vert (appdata v)
  62. {
  63. v2f o;
  64. o.worldPosition = v.vertex;
  65. o.vertex = UnityObjectToClipPos(o.worldPosition);
  66. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  67. return o;
  68. }
  69. fixed4 frag (v2f i) : SV_Target
  70. {
  71. fixed4 col = tex2D(_MainTex, i.uv);
  72.  
  73. #ifdef UNITY_UI_CLIP_RECT
  74. col.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect);
  75. #endif
  76. #ifdef UNITY_UI_ALPHACLIP
  77. clip (col.a - 0.001);
  78. #endif
  79.  
  80. return col;
  81. }
  82. ENDCG
  83. }
  84. }
  85. }

UnityGet2DClipping()方法在UnityUI.cginc文件中

  1. #ifndef UNITY_UI_INCLUDED
  2. #define UNITY_UI_INCLUDED
  3.  
  4. inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
  5. {
  6. float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
  7. return inside.x * inside.y;
  8. }
  9.  
  10. inline fixed4 UnityGetUIDiffuseColor(in float2 position, in sampler2D mainTexture, in sampler2D alphaTexture, fixed4 textureSampleAdd)
  11. {
  12. return fixed4(tex2D(mainTexture, position).rgb + textureSampleAdd.rgb, tex2D(alphaTexture, position).r + textureSampleAdd.a);
  13. }
  14. #endif


C#代码

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class UIClipTest : MonoBehaviour {
  6.  
  7. public Rect buttonRect = new Rect(0, 0, 400, 40);
  8. public Vector4 clipRect;
  9. public Texture2D mainTex;
  10. public MeshRenderer meshRenderer;
  11.  
  12. void Start () {
  13. meshRenderer = this.GetComponent<MeshRenderer>();
  14. }
  15. void OnGUI () {
  16. if (GUI.Button(buttonRect, "Clip")) {
  17. SetColorPropertyBlock(meshRenderer);
  18. }
  19. }
  20.  
  21. private void SetColorPropertyBlock(Renderer renderer)
  22. {
  23. //这种方式不会创建新的Material
  24. MaterialPropertyBlock properties = new MaterialPropertyBlock();
  25. properties.SetTexture(
  26. "_MainTex", mainTex
  27. );
  28. properties.SetVector(
  29. "_ClipRect", clipRect
  30. );
  31. renderer.SetPropertyBlock(properties);
  32. }
  33. }


工程截图

111111.png

qqqq11111.pngqqqqq222222.png

运行效果

3333.png

标签: Shader

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号