.. There is nothing new under the sun.
UGUI InvertMask - 反向遮罩
🌴 介绍
反向遮罩是一种常见的 UI 效果,用于反转遮罩区域,使得原本被遮罩的部分显示出来,而未被遮罩的部分被隐藏。这种效果常用于制作镂空 UI 或复杂的遮罩形状。
🛠️ 功能实现
创建 InvertMask.cs
1using UnityEngine;
2using UnityEngine.UI;
3using UnityEngine.Rendering;
4
5public class InvertMask : Image
6{
7 public override Material materialForRendering
8 {
9 get
10 {
11 Material material = new Material(base.materialForRendering);
12 material.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
13 return material;
14 }
15 }
16}
InvertMask 类继承自 UnityEngine.UI.Image,通过重写 materialForRendering 属性并修改材质渲染属性,实现了遮罩的反转效果。
materialForRendering 是 UnityEngine.UI.Graphic 类中的一个属性,用于获取或设置用于渲染的材质。当 UI 元素(如 Image)被渲染时,Unity 会调用这个属性来获取材质。
将组件添加到场景中
- 创建一个 Canvas 和 Image 作为背景。
- 在背景上添加 Mask 组件,并取消勾选 ShowMaskGraphic。
- 创建一个子对象,添加 InvertMask 组件。
- 调整子对象的大小和位置,观察反向遮罩的效果。
✍️ 原理分析
Unity 的遮罩系统通常使用模板测试(Stencil Test)来实现。这是一种 GPU 渲染技术,通过比较模板缓冲区中的值来决定是否渲染某个像素。默认情况下,遮罩区域会写入一个特定的模板值,而遮罩外的区域会被丢弃。
1material.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
这行代码将材质的模板比较函数(_StencilComp)设置为 CompareFunction.NotEqual。这意味着,只有当模板缓冲区中的值与当前模板值不相等时,才会渲染像素。因此,原本被遮罩的区域会被渲染,而原本未被遮罩的区域会被丢弃,从而实现遮罩的反转效果。
CompareFunction 是 Unity 提供的一个枚举类型,用于定义模板测试(Stencil Test)或深度测试(Depth Test)中的比较函数。
枚举值包括:
- Never:永远不通过测试。
- Less:小于时通过。
- Equal:等于时通过。
- LessEqual:小于或等于时通过。
- Greater:大于时通过。
- NotEqual:不等于时通过。
- GreaterEqual:大于或等于时通过。