Unity UI - 将蒙版应用于单个精灵而非整个纹理

4
我正在尝试对从大型纹理中剪切出来的精灵(精灵模式为“multiple”)应用遮罩,以便在UnityEngine.UI.Image组件中使用,但目前结果不尽如人意。
这是我正在使用的着色器,我从这里复制了它。
Shader "UI/Mask"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _MaskTex ("Mask Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)

        _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
    }

    SubShader
    {
        Tags
        { 
            "Queue"="Transparent" 
            "IgnoreProjector"="True" 
            "RenderType"="Transparent" 
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp] 
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }

        Cull Off
        Lighting Off
        ZWrite Off
        ZTest [unity_GUIZTestMode]
        Blend SrcAlpha OneMinusSrcAlpha
        ColorMask [_ColorMask]

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;
            };

            fixed4 _Color;


            v2f vert(appdata_t IN)
            {
                v2f OUT;
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                OUT.texcoord = IN.texcoord;
                #ifdef UNITY_HALF_TEXEL_OFFSET
                OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
                #endif
                OUT.color = IN.color * _Color;
                return OUT;
            }

            sampler2D _MainTex;
            sampler2D _MaskTex;

            fixed4 frag(v2f IN) : SV_Target
            {
                half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
                half4 mask = tex2D(_MaskTex, IN.texcoord);

                color.a *= mask.r;
                clip (color.a - 0.01);
                return color;
            }
            ENDCG
        }
    }
}

我有一条纹理,将其切割成单个的精灵。下面的图片展示了存储在同一个PNG文件中的前两个图标。

Icons put inside a main texture

接下来,我按照链接上的答案指示准备了一个面罩PNG,这只是一个半径为128像素的黑色边框圆形。

circle-256.png

然后准备材料...

Material prepared

并应用。

Material applied

这是我得到的:

enter image description here

很抱歉,我对着色器没有任何了解,因此不确定是否正确描述了问题...但是显然,圆形遮罩被压缩/拉伸并应用于长条纹理上,而不是应用于被剪切出来的单个图标。

换句话说,整个条带看起来像这样:

Full strip

但Unity正在做这件事:

Imaginary effect of what Unity's doing

我需要从错误遮罩纹理中裁剪出每个图标以供使用。

有什么方法可以让着色器正确地进行遮罩处理?所以我应该看到像这样的东西:

Desired effect

或者说这没有简单的方法,因为素材应该按照这种方式工作,所以我必须分别给Unity提供纹理,而不是将所有图标存储在一个长条中?

尝试勾选“保留纵横比”选项。这将使圆形保持为圆形。您可能需要调整其大小和位置。另外,看起来您正在为两个项目使用相同的遮罩,因为教师似乎得到了边缘,而学生则得到了更多的中心部分。您需要两个遮罩实例。 - Everts
谢谢您的回复,但保留纹理似乎不起作用。也许我的解释不够清楚。我已经添加了两张图片来详细说明问题。这应该能解释为什么教师按钮会得到边缘,而学生按钮会得到更多的中心部分。您是说我需要在Unity项目中为每个使用的图标创建N个材质实例吗? - Felastine
看起来你的按钮都在一个主对象下面,该对象有一个遮罩。你需要的层次结构是一个主对象,然后在它下面有 N 个遮罩对象,每个对象都有一个带有保持纵横比的图像和遮罩组件,然后在每个对象下面都有你的 N 个对象,包括教师/学生等等。每个遮罩将覆盖其自己的子对象。 - Everts
哦,恐怕你误解了。我并没有使用UI遮罩系统,因为它存在走样问题(http://answers.unity3d.com/questions/942614/aliasing-when-using-ui-mask.html),而这个问题还未得到修复。所以我现在转而使用着色器来遮罩精灵。 - Felastine
1个回答

1
好的,这里是一种临时解决方案。 首先,用于遮罩的圆形图像需要将其纹理包裹模式设置为Repeat。
然后,找到这行代码:
half4 mask = tex2D(_MaskTex, IN.texcoord);

在此之前插入以下代码:
IN.texcoord.x *= 9;
half4 mask = tex2D(_MaskTex, IN.texcoord);

这将把你的一个跨越9个精灵的圆形变为在9个精灵上重复出现的9个圆形。(如果你有超过9个精灵,则需要更改此设置。)希望能对你有所帮助!

这个可以用。对于我的情况来说是这样的: IN.texcoord.x *= 10; IN.texcoord.y *= 2; 因为我有每行10个图标,共有2行。虽然它确实有效,但这个掩码只能用于特定的2 x 10图标映射,如果用于其他任何东西,它将绘制出奇怪的形状。 - Felastine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接