Unity基础 —— RectMask2D 与 Mask
目录
RectMask2D 与 Mask 组件深度对比
在 Unity UGUI 优化中,选择合适的裁剪组件对 DrawCall 和内存性能有显著影响。以下是两者的核心区别及性能差异分析。
1. 核心原理区别
Mask (基于模板缓冲)
Mask 组件利用了显卡的 Stencil Buffer (模板缓冲)。
- 工作流程:
- 绘制 Mask 原型区域,向 Stencil Buffer 写入一个特定值。
- 绘制子物体时,进行模板测试(Stencil Test),只有在 Stencil Buffer 值匹配的像素点才进行渲染。
- 绘制完子物体后,再次绘制 Mask 以清理 Stencil Buffer。
- 特性:支持任意形状的裁剪(取决于 Image 的 Alpha 通道),甚至可以做圆角或异形遮罩。
RectMask2D (基于 Shader 裁剪)
RectMask2D 利用了 Shader 中的坐标剔除(通常是 C++ 层的裁剪矩形传递给 GPU)。
- 工作流程:
- 计算 RectMask2D 指定的矩形区域坐标(世界坐标)。
- 将该矩形区域的四角坐标作为参数传递给子物体的 Shader。
- Shader 在片段着色器中通过简单的坐标逻辑判断:如果像素点在矩形外,则丢弃(discard)该像素。
- 特性:仅支持矩形裁剪,不支持旋转(旋转后裁剪区域依然是轴对齐矩形)。
2. 为什么 RectMask2D 性能更好?
RectMask2D 性能优于 Mask 主要体现在以下三个维度:
A. DrawCall (合批效率)
- Mask 会打断合批:由于 Mask 需要切换 Stencil Buffer 状态,它至少会增加 2 个额外的 DrawCall(一个进入遮罩,一个离开遮罩)。更严重的是,遮罩内外的相同图集元素无法合批。
- RectMask2D 不打断合批:它不改变渲染状态(不使用模板测试),因此遮罩外的元素与遮罩内的元素(如果图集和材质相同)有机会合并为一个 DrawCall。
B. GPU 计算开销
- Mask 的 Stencil 测试:每绘制一个像素都要进行模板缓冲的读写和比对。
- RectMask2D 的坐标判断:片段着色器中仅需几行极简的数学运算(类似
if (pos.x < min.x || pos.x > max.x) discard;),对于现代 GPU 几乎是免费的。
C. 重绘 (Rebuild) 开销
Mask组件需要维护一个特殊的材质实例来处理模板逻辑。RectMask2D逻辑更轻量,不涉及复杂的模板状态切换,在 UI 频繁重建时 CPU 压力更小。
3. 性能对比总结表
| 特性 | Mask 组件 | RectMask2D 组件 |
|---|---|---|
| 裁剪形状 | 任意形状(依赖 Image 资源) | 仅限矩形 |
| DrawCall 开销 | 显著增加(+2 且打断合批) | 极低(几乎不增加) |
| GPU 压力 | 模板测试,有一定像素开销 | 简单的坐标逻辑判断 |
| 适用场景 | 圆形头像、异形 UI 遮罩 | 滚动列表 (ScrollView)、背包翻页 |
| 嵌套支持 | 支持,但每层嵌套都会翻倍增加 DC | 支持,性能损耗极小 |
4. 开发建议
- 首选 RectMask2D:对于 90% 的列表滚动、区域裁剪需求,请务必使用
RectMask2D。 - 避免在列表里用 Mask:如果在每一项(Item)里都加一个
Mask,DrawCall 会随着 Item 数量暴增。 - 异形需求才用 Mask:只有当策划要求“圆角裁剪”或“非矩形遮罩”时,才考虑使用
Mask,且尽量控制层级。 - 注意裁剪区域外渲染:虽然两者都能隐藏视觉上的像素,但子物体的 CPU 逻辑(如动画、Layout 计算)依然在运行。如果列表极长,请配合 UI 循环列表(LoopScrollRect) 使用,真正销毁或禁用屏幕外的对象。

浙公网安备 33010602011771号