Unity UI - 将遮罩应用于单个精灵而不是整个纹理
Unity UI - Applying mask to individual sprites instead of entire texture
我正在尝试对从大型纹理(精灵模式 "multiple")中切出的精灵应用遮罩,这些精灵将用于 UnityEngine.UI.Image 组件,但到目前为止结果并不令人满意。
这是我正在使用的着色器,我将其复制下来 here。
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 中。
接下来,我按照 link 答案的说明准备了一个蒙版 PNG,它只是一个半径为 128 像素的黑色边框圆圈。
然后material准备好...
并应用。
这是我得到的:
很遗憾,我对着色器一无所知,所以我不知道我是否正确描述了问题...但显然,圆形蒙版是 squashed/stretched 并应用于长条纹理,而不是应用于切出的单个图标。
换句话说,完整的条带是这样的:
但 Unity 正在这样做:
然后它从错误蒙版的纹理中剪下每个图标供我使用。
可以对着色器做些什么来使其正确遮罩?所以我应该看到这样的东西:
或者没有简单的方法,因为这就是 material 应该如何工作所以我必须给 Unity 单独的纹理而不是将所有图标存储在一个长条中?
好的,这是一种临时操纵的解决方案。
首先,您用于蒙版的圆形图像需要将其纹理环绕模式设置为重复。
然后,找到这行代码:
half4 mask = tex2D(_MaskTex, IN.texcoord);
并在其前面插入这行代码:
IN.texcoord.x *= 9;
half4 mask = tex2D(_MaskTex, IN.texcoord);
这会将在 9 个精灵上延伸的一个圆圈变成在 9 个精灵上重复的 9 个圆圈。 (如果你有超过 9 个精灵,你需要改变这个。)
希望对您有所帮助!
我正在尝试对从大型纹理(精灵模式 "multiple")中切出的精灵应用遮罩,这些精灵将用于 UnityEngine.UI.Image 组件,但到目前为止结果并不令人满意。
这是我正在使用的着色器,我将其复制下来 here。
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 中。
接下来,我按照 link 答案的说明准备了一个蒙版 PNG,它只是一个半径为 128 像素的黑色边框圆圈。
然后material准备好...
并应用。
这是我得到的:
很遗憾,我对着色器一无所知,所以我不知道我是否正确描述了问题...但显然,圆形蒙版是 squashed/stretched 并应用于长条纹理,而不是应用于切出的单个图标。
换句话说,完整的条带是这样的:
但 Unity 正在这样做:
然后它从错误蒙版的纹理中剪下每个图标供我使用。
可以对着色器做些什么来使其正确遮罩?所以我应该看到这样的东西:
或者没有简单的方法,因为这就是 material 应该如何工作所以我必须给 Unity 单独的纹理而不是将所有图标存储在一个长条中?
好的,这是一种临时操纵的解决方案。 首先,您用于蒙版的圆形图像需要将其纹理环绕模式设置为重复。
然后,找到这行代码:
half4 mask = tex2D(_MaskTex, IN.texcoord);
并在其前面插入这行代码:
IN.texcoord.x *= 9;
half4 mask = tex2D(_MaskTex, IN.texcoord);
这会将在 9 个精灵上延伸的一个圆圈变成在 9 个精灵上重复的 9 个圆圈。 (如果你有超过 9 个精灵,你需要改变这个。)
希望对您有所帮助!