Unity遮罩Mask原理 📅 2026/7/8 2:18:51 在Unity中Mask遮罩是UIUGUI系统中非常核心的一个功能用于限制子UI元素的可见区域。Unity主要提供了两种Mask实现方式Stencil Mask普通Mask和2D Rect MaskRectMask2D。它们的实现原理截然不同适用于不同的场景。1. 基础版 Mask基于 Stencil Buffer 模板缓冲我们在组件列表中直接添加的Mask组件其底层是基于 GPU 的模板缓冲区Stencil Buffer实现的。 实现原理模板缓冲是渲染管线Render Pipeline中的一块屏幕空间的缓存大小通常与颜色缓冲区一致。它像一个“像素级别的印章”决定了像素是否应该被渲染。其工作流程可以分为以下三步绘制遮罩区域写入模板当一个带有Mask组件的 UI 节点被渲染时它会向 GPU 发出指令在特定区域的 Stencil Buffer 中写入一个特定的数值默认通常是 1。绘制子物体模板测试接着渲染该 Mask 下的子 UI 元素。子物体使用的 Shader 会开启模板测试Stencil Test。测试规则通常是只有当屏幕对应位置的 Stencil Buffer 值为 1时才允许通过测试并渲染。还原模板清理当所有子物体渲染完毕后Mask 会再渲染一次或者通过特殊材质将 Stencil Buffer 中之前写入的值清空改回 0以免影响画布Canvas上其他不相干的 UI 元素。⚠️ 缺点DCDraw Call杀手普通 Mask 的最大劣势在于它会破坏 UGUI 的动态批处理Canvas Batching。Mask 节点自身需要单独的 Draw Call 来写入模板。Mask 内部的子物体无法与 Mask 外部的物体进行合批。即使两个 Mask 完全一模一样它们各自的子物体也无法跨 Mask 合批。会导致 Draw Call 激增。2. 升级版 RectMask2D基于 2D 矩形剪裁RectMask2D是针对矩形区域定制的轻量级遮罩常用于 ScrollView滚动视图。 实现原理RectMask2D不依赖GPU 的模板缓冲而是纯粹通过Shader 传递逻辑坐标轴来实现的。其工作流程如下计算世界坐标矩形RectMask2D 组件在 CPU 端会计算出自己这个矩形框在世界空间下的四个边界坐标或者一个Vector4代表[左, 下, 右, 上]。材质参数传递Canvas 在渲染 RectMask2D 内部的子物体时会将这个矩形的边界坐标作为参数如_ClipRect传递给子物体的 Shader。片元着色器Fragment Shader裁剪子物体使用的 Shader通常是 UGUI 默认的 UI Shader 变体在片元着色器中会执行一步计算检查当前像素的世界坐标是否在这个矩形范围内。如果在范围内正常输出颜色。如果在范围外直接执行discard丢弃该像素或将其 Alpha 值设为 0。 优点性能极佳不破坏合批由于它只是在 Shader 里做坐标判断如果多个 RectMask2D 处于相同的层级和逻辑下它们的子物体甚至可以跨遮罩进行合批Batching。没有额外的 Draw Call它不需要像普通 Mask 那样单独绘制一次去写模板缓冲。⚠️ 限制只能是矩形无法实现圆形、星形等异形遮罩。不支持旋转如果 RectMask2D 或其父物体旋转了裁剪依然是基于轴对齐矩形AABB的会导致裁剪边缘不正确。 总结与选型指南特性Mask (普通遮罩)RectMask2D (矩形遮罩)底层原理GPU 模板缓冲 (Stencil Buffer)Shader 坐标裁剪 (discard/Alpha0)形状支持任意形状依赖 Image 的像素 Alpha仅限矩形且不能旋转Draw Call 消耗高破坏合批增加至少 2 个 DC低支持合批无额外 DC常见应用场景圆形头像、异形小地图、UI 镂空引导聊天列表、背包滚动条 (ScrollView)开发建议在做 UI 时优先使用RectMask2D。只有当策划或美术明确提出需要“圆形”、“心形”或带羽化边缘的复杂遮罩时才考虑使用Mask。