Unity基础 —— RectMask2D 与 Mask

RectMask2D 与 Mask 组件深度对比

在 Unity UGUI 优化中,选择合适的裁剪组件对 DrawCall 和内存性能有显著影响。以下是两者的核心区别及性能差异分析。


1. 核心原理区别

Mask (基于模板缓冲)

Mask 组件利用了显卡的 Stencil Buffer (模板缓冲)

  • 工作流程
    1. 绘制 Mask 原型区域,向 Stencil Buffer 写入一个特定值。
    2. 绘制子物体时,进行模板测试(Stencil Test),只有在 Stencil Buffer 值匹配的像素点才进行渲染。
    3. 绘制完子物体后,再次绘制 Mask 以清理 Stencil Buffer。
  • 特性:支持任意形状的裁剪(取决于 Image 的 Alpha 通道),甚至可以做圆角或异形遮罩。

RectMask2D (基于 Shader 裁剪)

RectMask2D 利用了 Shader 中的坐标剔除(通常是 C++ 层的裁剪矩形传递给 GPU)。

  • 工作流程
    1. 计算 RectMask2D 指定的矩形区域坐标(世界坐标)。
    2. 将该矩形区域的四角坐标作为参数传递给子物体的 Shader。
    3. 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. 开发建议

  1. 首选 RectMask2D:对于 90% 的列表滚动、区域裁剪需求,请务必使用 RectMask2D
  2. 避免在列表里用 Mask:如果在每一项(Item)里都加一个 Mask,DrawCall 会随着 Item 数量暴增。
  3. 异形需求才用 Mask:只有当策划要求“圆角裁剪”或“非矩形遮罩”时,才考虑使用 Mask,且尽量控制层级。
  4. 注意裁剪区域外渲染:虽然两者都能隐藏视觉上的像素,但子物体的 CPU 逻辑(如动画、Layout 计算)依然在运行。如果列表极长,请配合 UI 循环列表(LoopScrollRect) 使用,真正销毁或禁用屏幕外的对象。
posted @ 2026-04-17 00:12  Reed_Chill  阅读(147)  评论(0)    收藏  举报