使自定义的Shader支持Mask裁剪

昨天写了一篇技术博客,一时手痒,把之前解决过的问题也拿出来分享一下吧

还是别的项目组遇到了一个问题,他们找了一个Shader,但是发现这个Shader不能被UGUI的Mask所裁剪,网上搜索了一下解决方案,不过是英文的,这里搬运并翻译一下。

Unity论坛原文:
http://answers.unity3d.com/questions/980924/ui-mask-with-shader.html

关键代码
在Properties中增加以下代码

Shader "xxxxxx"  
{
    Properties
    {
    ......

        //MASK SUPPORT ADD
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255
        _ColorMask ("Color Mask", Float) = 15
        //MASK SUPPORT END
    }
}

在SubShader中增加以下代码

SubShader  
{
    Tags {...}

    //MASK SUPPORT ADD
    Stencil
    {
        Ref [_Stencil]
        Comp [_StencilComp]
        Pass [_StencilOp] 
        ReadMask [_StencilReadMask]
        WriteMask [_StencilWriteMask]
    }
    ColorMask [_ColorMask]
    //MASK SUPPORT END
......
}

在你的 Shader 中加入这2段代码,剩下的部分照旧。这时我们再把这个 Shader 赋给 UGUI 组件的时候,就发现 mask 组件可以正确的剔除被我们更换过材质球的组件了。

PS:其实Mask的主要功能,计算都在UI组件上了,加上这2段以后,我们就可以正确的接受外部传入进来的Mask相关参数了,剩下的就是把它们剔除掉就好了。

补充一下:在支持Mask之后,在Mask组件下的Image等组件的Material只有第一次赋值有效,如果想要能动态修改的话,就要新建一个脚本继承Image并重写 GetModifiedMaterial 方法。

kisence

潮落江平未有风。