..

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 会调用这个属性来获取材质。

将组件添加到场景中

  1. 创建一个 Canvas 和 Image 作为背景。
  2. 在背景上添加 Mask 组件,并取消勾选 ShowMaskGraphic。
  3. 创建一个子对象,添加 InvertMask 组件。
  4. 调整子对象的大小和位置,观察反向遮罩的效果。

✍️ 原理分析

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:大于或等于时通过。

Reference

  1. Make a Cutout Mask in Unity! (Inverted Mask)
There is nothing new under the sun.