Маска для спрайта [2D]
При разработки двухмерной игрушки, порой может возникнуть необходимость обрезки спрайта по форме некой маски. Например, если игра с изометрическим видом и нужно показать, как допустим зомби выползает из ямы, в этой ситуации, использование маски будет очень удобным решением. Для реализации мы воспользуемся шейдерами, один для маски, а второй для спрайта, который должен взаимодействовать с маской. То бишь, у нас будет выбор, если на спрайте использовать стандартный шейдер, то это будет обычный спрайт, что крайне удобно. Представленные ниже шейдеры были найдены на просторах интернета, поэтому давайте разберемся, как их задействовать в игре.
Для начала создадим шейдеры.
Первый, для спрайта маски:
Далее, второй шейдер для взаимодействия с первым:
Теперь, нам нужно создать два материала, Mask и DrawInMask и выбрать шейдеры.
![Маска для спрайта [2D]](/uploads/posts/2016-07/1467707830_1.png)

Собственно вот и всё.
Если нам нужна маска, то просто добавляем на спрайт соответствующий материал.

А для спрайтов которые нужно обрезать маской используем материал DrawInMask.
Скачать демо:
Для начала создадим шейдеры.
Первый, для спрайта маски:
Shader "Custom/Sprites/Mask"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_Color("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
[MaterialToggle] ShowTexture("Show Texture", Float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
Stencil
{
Ref 1
Comp always
Pass replace
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ SHOWTEXTURE_ON
#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 SHOWTEXTURE_ON
OUT.color = IN.color * _Color;
#else
OUT.color = IN.color * _Color;
OUT.color.rgb = 0;
#endif
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap(OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
if (c.a < 0.2) discard;
c.rgb *= c.a;
c.a = 0;
return c;
}
ENDCG
}
}
}
Далее, второй шейдер для взаимодействия с первым:
Shader "Custom/Sprites/Draw In Mask"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_Color("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent+1"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
Stencil
{
Ref 0
Comp Equal
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#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;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap(OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
sampler2D _AlphaTex;
float _AlphaSplitEnabled;
fixed4 SampleSpriteTexture(float2 uv)
{
fixed4 color = tex2D(_MainTex, uv);
if (_AlphaSplitEnabled)
color.a = tex2D(_AlphaTex, uv).r;
return color;
}
fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}
Теперь, нам нужно создать два материала, Mask и DrawInMask и выбрать шейдеры.
![Маска для спрайта [2D]](/uploads/posts/2016-07/1467707830_1.png)

Собственно вот и всё.
Если нам нужна маска, то просто добавляем на спрайт соответствующий материал.

А для спрайтов которые нужно обрезать маской используем материал DrawInMask.
Скачать демо:
Тестировалось на: Unity 5.3.5
Комментариев 4
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.