对 2D UI 元素(如 Image、RawImage、Text)进行矩形区域裁剪,隐藏超出矩形范围的部分。
使用方法
添加组件
RectMask2D 的工作原理是通过将裁剪矩形 _ClipRect 传递给子物体所使用的 Shader 来实现裁剪的,故首先需要添加RectMask2D组件作为父级。
在Shader代码中可添加变体UNITY_UI_CLIP_RECT来处理RectMask2D裁剪相关的逻辑:
#pragma multi_compile _ UNITY_UI_CLIP_RECT声明变量
直接声明变量_ClipRect,不需要定义属性(Properties)。
float4 _ClipRect;变量含义:矩形裁剪区域坐标(模型空间)(xMin, yMin, xMax, yMax)
实现裁剪
核心思路:根据坐标判断在裁剪区域内的像素保留,区域外的剔除。
#ifdef UNITY_UI_CLIP_RECT
if(IN.positionOS.x > _ClipRect.x && IN.positionOS.y > _ClipRect.y && IN.positionOS.x < _ClipRect.z && IN.positionOS.y < _ClipRect.w)
clip(0);
else
clip(-1);
#endif使用step函数:
#ifdef UNITY_UI_CLIP_RECT
float2 r = step(_ClipRect.xy, IN.positionOS.xy) * step(IN.positionOS.xy, _ClipRect.zw);
clip(r.x * r.y - 1);
#endif使用内置函数:UnityGet2DClipping
需要引入UnityUI.cginc,该函数的实现就是step法
#include "UnityUI.cginc" // 引入库
// ...
{
#ifdef UNITY_UI_CLIP_RECT
clip(UnityGet2DClipping(IN.positionOS, _ClipRect) - 1);
#endif
}提示
注意使用模型空间坐标(局部坐标系)
RectMask2D 与 Mask
| 特性 | RectMask2D | Mask |
|---|---|---|
| 原理 | GPU 裁剪 | Stencil 模板缓冲区 |
| 额外DrawCall | 无 | 有(模板生成+遮罩渲染) |
| 填充率开销 | 低(仅逐像素裁剪计算) | 中高(需模板读写) |
| 非矩形支持 | ❌ 仅支持矩形 | ✅ 支持任意形状 |
| 锯齿边缘 | 硬边缘 | 可抗锯齿 |
注意事项
- RectMask2D嵌套: 当多个RectMask2D嵌套时,裁剪区域取交集。
- 内置Shader:
使用内置 UI Shader(如
UI/Default) 自动支持RectMask2D。
完整例子
Shader "ChaimLearn/UIShader"
{
Properties { }
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ UNITY_UI_CLIP_RECT
#include "UnityCG.cginc"
#include "UnityUI.cginc"
float4 _ClipRect; // 声明变量
struct Varyings {
float4 positionOS: TEXCOORD0;
float4 positionCS: SV_POSITION;
};
Varyings vert(float4 positionOS: POSITION) {
Varyings OUT;
OUT.positionOS = positionOS;
OUT.positionCS = UnityObjectToClipPos(positionOS);
return OUT;
}
half4 frag(Varyings IN): SV_TARGET {
#ifdef UNITY_UI_CLIP_RECT
clip(UnityGet2DClipping(IN.positionOS, _ClipRect) - 1);
#endif
return 1;
}
ENDHLSL
}
}
}