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