Unity图片与文字的渐变遮罩

在做功能时美术有个效果是UGUI的渐变透明,实现上可以用遮罩,但是Unity提供的遮罩RectMask2D是硬裁剪,即超出遮罩范围就alpha直接设为0,没有过渡,所以我就要给这个图片设一个自定义shader让它能支持alpha渐变。

其实就是修改下Unity的UI Default shader,但注意Unity在下载时每个版本都提供了内置着色器,所以你还要选择对应的Unity版本的内置着色器代码。

将UI Default shader的UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);替换为自定义函数,UI Default代码不放了,要从对应版本的Unity(官网)下载,我一开始从网上找了个UI Default shader可能因为接口对不上,连遮罩都不成功。

 

从Unity的安装目录下找到CGIncludes/UnityUI.cginc

inline float UnityGet2DClipping (in float2 position, in float4 clipRect)
{
    float2 inside = step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw);
    return inside.x * inside.y;
}

clipReect传入的是float4,clipRect.xy是左上遮罩的裁剪位置,clipRect.zw是右下遮罩的裁剪位置.

 

step()用法:https://developer.download.nvidia.cn/cg/step.html

step - implement a step function returning either zero or one

 

step(clipRect.xy, position.xy) * step(position.xy, clipRect.zw)
即position.xy >= clipRect.xy返回1,同样position.xy < clipRect.zw返回1,虽然参数是float3,但传fix/fix2/fix3/fix4, half~half4, float~float4都可以cg内部帮我们做了转换。
step的操作减少了gpu做比较运算的消耗,gpu不适合做<这类运算,那是cpu擅长的。
通过这一步,可以判断这个世界座标在clipRect内否,不满足在内部,则直接设置alpha=0,刚好step() * step()计算后在clipRect外的返回值为0.



SoftUnityGet2DClipping软裁剪
使用的是雨松momo的裁剪,https://www.xuanyusong.com/archives/4650,momo还用UGUI的方式裁剪了模型,我做的功能倒不需要裁剪模型。
float _ClipSoftX;
    float _ClipSoftY;
    inline float SoftUnityGet2DClipping(in float2 position, in float4 clipRect)
    {
        float2 xy = (position.xy - clipRect.xy) / float2(_ClipSoftX, _ClipSoftY)*step(clipRect.xy, position.xy);
        float2 zw = (clipRect.zw - position.xy) / float2(_ClipSoftX, _ClipSoftY)*step(position.xy, clipRect.zw);
        float2 factor = clamp(0, zw, xy);
        return saturate(min(factor.x, factor.y));
    }

 做裁剪区域判定时,添加了类似下面的代码,将裁剪内的座标alpha添加一个除法,除以我需要软化的边缘像素值,比如

(position.xy - clipRect.xy) / float2(_ClipSoftX, _ClipSoftY)
_ClipSoftX=15,position距离clipRect 15座标单位的点,其alpha为距离/15。


clamp - returns smallest integer not less than a scalar or each vector component.

 factor是在距离左上和右下边距里,取个离边距最近的alpha值。

 

saturate - returns smallest integer not less than a scalar or each vector component.

Returns x saturated to the range [0,1] as follows:

https://developer.download.nvidia.cn/cg/saturate.html

最后将输出值规范化为0~1区间内的值。

 

效果:

 

 

TMP直接提供了渐变参数,在Debug Settings-Softness X,放在RectMask2D里会软化左右X方向的裁剪。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章